2011-04-08 97 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) { ... }