2

私のアプリケーションの検索を実行している最適化を書いています。文字列が IP アドレスのように見える場合は、MAC アドレスを検索する必要はありません。また、検索が MAC アドレスのように見える場合は、わざわざ IP アドレスのデータベース列を調べないでください。

ips と mac アドレスが完全に一致する表現は見たことがありますが、部分的な文字列と非常に楽しい頭の体操に一致するものを見つけるのは難しく、他の人の意見が得られると思いました。現在、正規表現を使用しないソリューションがあります。

use List::Util qw(first);

sub query_is_a_possible_mac_address {
  my ($class, $possible_mac) = @_;
  return 1 unless $possible_mac;

  my @octets = split /:/, $possible_mac, -1;
  return 0 if scalar @octets > 6; # fail long MACS
  return 0 if (first { $_ !~ m/[^[:xdigit:]]$/ } @octets; # fail any non-hex characters
  return not first { hex  $_ > 2 ** 8 }; # fail if the number is too big
}

# valid tests
'12:34:56:78:90:12'
'88:11:'
'88:88:F0:0A:2B:BF'
'88'
':81'
':'
'12:34'
'12:34:'
'a'
''

# invalid tests
'88:88:F0:0A:2B:BF:00'
'88z'
'8888F00A2BBF00'
':81a'
'881'
' 88:1B'
'Z'
'z'
'a12:34'
' '
'::88:'
4

2 に答える 2

1

(新しい)テストを考えると、これは機能します:

/^[0-9A-Fa-f]{0,2}(:[0-9A-Fa-f]{2}){0,5}:?$/

上記のテストで一致する行は次のとおりです(「a」や「A」などの単一の16進文字が正しく一致することに注意してください。

12:34:56:78:90:12
88:11:
88:88:F0:0A:2B:BF
88
:81
:
12:34
12:34:
a
'' (<-- empty space)
于 2012-06-05T00:06:53.100 に答える
0

これを行うために私が見つけた最善の方法は、可能な一致をあなたが一致させようとしているものにしようとすることでした。たとえば、文字列:1.2がある場合は、IPアドレス:1.2.1.1のように見せてみてください。次に、正規表現を適用します

sub contains_ip {
    my ($possible_ip) = @_;

    my @splits = split /\./, $possible_ip;

    return 0 if @splits > 4;
    while (@splits < 4) {
        push @splits, '1';
    }

    $possible_ip = join '.', @splits;

    my ($match) = $possible_ip =~ m/^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/;
    return defined $match ? 1 : 0;
}

warn contains_ip('1.2'); # 1
warn contains_ip('127.0.0.1'); # 1
warn contains_ip('1.2asd'); # 0
warn contains_ip('1.2.3.4.5'); # 0

同じことがMacアドレスにも当てはまります。11:22の場合は、完全修飾MACアドレス11:22:00:00:00:00のように見せてから、Macアドレスの正規表現を適用します。

于 2012-07-17T16:09:35.437 に答える