2011-04-08 127 views
11

到現在爲止,如果我內if語句想將幾個正則表達式的,我就是這麼做的:Perl的正則表達式中的if語句[語法]

my $data =... 
if ($data =~ m/regex/ && $data =~ m/secondregex/) {...} 

是否有一個快捷方式(和我」 m確定有,它的Perl!)以避免重複$數據,例如:

if ($data =~ m/regex/ && m/secondregex/) {..} 

??

感謝,

+1

你能舉個例子模式?您應該能夠將兩種模式合併爲一個模式。 – halfdan 2011-04-08 10:52:19

+0

爲什麼你需要兩個正則表達式?如果它與&&測試我敢打賭,它可以是單一的表達。[編輯]哦,我遲到了:) +1 halfdan – tmg 2011-04-08 10:55:31

+3

如果你將它們組合成一個單一的正則表達式,你將需要結合所有可能的順序,其中子模式可以出現在單個字符串中,生成更復雜的正則表達式來測試。對於兩個正則表達式,它將是'm /^(?:.** regex。* secondregex。*)|(?:。* secondregex。* regex。*)$ /'對於三個或更多,它變得很難看。 – BoltClock 2011-04-08 10:56:54

回答

17

使用默認的變量$_這樣的:

$_ = $data; 
if (m/regex/ && m/secondregex/) {..} 

爲正則表達式(在Perl中許多其他的東西)作用於$_默認。

只要確定您不在$ _自動填充的塊中,您需要稍後在此塊中使用它。一旦它被覆蓋就消失了。

+10

你可能想本地化'$ _':'local $ _ = $ data' – 2011-04-08 11:37:01

+0

Sweet Solution!謝謝 – snoofkin 2011-04-08 12:01:34

+0

賦值給一個隱式變量看起來對我來說有點破綻。 – BillMan 2016-10-26 17:17:45

14
for ($data) { 
    if (/regex/ && /secondregex/) {...} 
} 
+4

對於我來說,這看起來比清晰地分配給本地化的$ _更類似於其他語言中的「with」和類似結構。 – 2011-04-08 12:16:46

0

取決於你的條件結構。您也可以使用嵌套ifs重構一些正則表達式。

即:改變

if (/regex1/ && /regex2/) block1 
elsif (/regex2/ && /regex3/) block2 

if (/regex2/){ 
    if (/regex1/) block1 
    else (/regex3/) block2 
} 
2

一個建議。取決於你需要匹配多長時間的正則表達式列表,以及需要多長時間才能完成此類事情,將其轉化爲子例程會很有意義。

靈感來自Ruby的每個:

sub matchesAll ([email protected]) { 
    my $string = shift; 
    my $result = 1; 
    foreach $_ (@_) { 
    $result &&= $string =~ $_; 
    } 
    $result; 
} 

然後做

if (matchesAll $data, $regex1, $regex2, $regex3, $regex4) ... 

注:這要求所有regexs使用QR // $regex1 = qr/regex1/

2

爲了增加以備將來使用編譯將$data置入$_的方法列表:

if (grep { m/regex/ && m/secondregex/ } $data) {...} 
6

使用智能匹配只有一行:

use 5.010; 
if ($data ~~ [qr/regex1/,qr/regex2/]) { ... } 
0

正確的方法來改變

if (/re1/ && /re2/ && /re3/) { ... } 

成一個單一的模式是這樣的:

if (/(?=.*re1)(?=.*re2)(?=.*re3)/s) { ... }