2012-06-04 105 views
2

我正在編寫一個優化,您正在爲我的應用程序執行搜索,並且如果字符串看起來像是一個IP地址,那麼請勿麻煩搜索MAC地址。如果搜索看起來像一個MAC地址,不要打擾在IP地址數據庫列。用於部分匹配IP或MAC地址的Perl正則表達式

我已經看到完全匹配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:' 
+0

可能重複的[MAC地址的正則表達式是什麼?](http://stackoverflow.com/questions/4260467/what-is-a-regular-expression-for-a-mac-address) – eggyal

+0

不,我想要一個包含MAC地址的正則表達式,而不是'是'一個MAC地址。 –

+0

MAC地址的另一個解決方案是用00s填充輸入。例如,您輸入11並將其填充爲11:00:00:00:00:00,然後將其通過MAC地址RegEx。對於IP甚至IPv6地址,您不能這樣做 –

回答

1

考慮到(新)的測試,這個工程:

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

下面是匹配給出了上述試驗線(注意,一個十六進制的字符,如「a」和「A」是正確的匹配:

12:34:56:78:90:12 
88:11: 
88:88:F0:0A:2B:BF 
88 
:81 
: 
12:34 
12:34: 
a 
'' (<-- empty space) 
+0

'A'=〜/^[0-9A-Fa-f] {0,2}(:[0-9A-Fa-f] {2}){0,5}:?$/yeilds me undef –

+0

我不認爲你的正則表達式的第一部分是正確的。它假定所有輸入在前面都有2個十六進制字符。對我而言,唯一的一次是當我獲得3個以上的字符時:例如:'AA:'。你錯過了角落案例 –

+0

嗯怪異;第一部分說它應該匹配0,1或2個十六進制字符,所以'A'應該匹配。在我的系統上,它給了我正確的輸出。我更新了我的答案,顯示我的輸出。 – Sicco

0

我發現要做到這一點,最好的辦法是試圖使可能的匹配成爲你想什麼來匹配,例如,如果你有一個字符串:1.2,試圖使它看起來像一個IP地址:1.2.1.1。然後a pply正則表達式

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地址正則表達式應用到它。