Regex 在';如果';语句[语法]

Regex 在';如果';语句[语法],regex,perl,syntax,Regex,Perl,Syntax,到目前为止,如果我想在一个if语句中组合几个正则表达式,我是这样做的: my $data =... if ($data =~ m/regex/ && $data =~ m/secondregex/) {...} if (/(?=.*re1)(?=.*re2)(?=.*re3)/s) { ... } 是否有一种避免重复$data的快捷方式(我肯定有;它是Perl!),例如: if ($data =~ m/regex/ && m/secondregex/) {..

到目前为止,如果我想在一个if语句中组合几个正则表达式,我是这样做的:

my $data =...
if ($data =~ m/regex/ && $data =~ m/secondregex/) {...}
if (/(?=.*re1)(?=.*re2)(?=.*re3)/s) { ... }
是否有一种避免重复$data的快捷方式(我肯定有;它是Perl!),例如:

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

??

使用默认变量
$\uu
如下:

$_ = $data;
if ( m/regex/ && m/secondregex/ ) {..}
默认情况下,正则表达式作用于
$\uu
(与Perl中的许多其他内容一样)


只需确保您不在自动填充$的块中,稍后您需要在该块中使用它。一旦它被覆盖,它就会消失。

取决于你的if条件结构。您还可以使用嵌套的ifs重构一些正则表达式

for ($data) {
    if (/regex/ && /secondregex/) {...}
}
即:改变

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


还有一个建议。根据需要在一个if中匹配的正则表达式列表的长度,以及需要执行此类操作的频率,将其转换为子例程将非常有意义

灵感来源于ruby的every:

sub matchesAll ($@) {
  my $string = shift;
  my $result = 1;
  foreach $_ (@_) {
    $result &&= $string =~ $_;
  }
  $result;
}
然后呢

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

注意:这要求使用qr/
$regex1=qr/regex1/

编译所有正则表达式,以供将来使用,从而添加到将
$data
放入
$\uucode>的方法列表中:

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

只有一行使用智能匹配:

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

改变的正确方式

if (/re1/ && /re2/ && /re3/) { ... }
通过以下方式将其转换为单个模式:

my $data =...
if ($data =~ m/regex/ && $data =~ m/secondregex/) {...}
if (/(?=.*re1)(?=.*re2)(?=.*re3)/s) { ... }

你能举个例子吗?您应该能够将两种模式合并为一种模式。为什么需要两个regexp?如果使用&&测试它,我打赌它可以是单个表达式。哦,我迟到了:)+1如果你把它们组合成一个正则表达式,你就需要把所有可能的顺序组合起来,子模式可以出现在一个字符串中,生成更复杂的正则表达式来进行测试。对于两个正则表达式,它将是
m/^(?:*regex.*secondregex.*)|(?:*secondregex.*regex.*regex.*)$/
对于三个或更多个正则表达式,它会变得难看。尝试将两个模式组合成一个模式通常比两个测试执行得更糟糕,并且您为了达到这一点而跳转的环通常会掩盖代码的真正意图。看@BoltClock:这是一个神话。您不需要所有可能的订单<代码>/(?=.*REGEX1)(?=.*REGEX2)/s
不依赖于顺序,并且线性扩展。它也适用于重叠。所有这些其他解决方案都失败了。您可能希望本地化
$\uuuz
local$\uz=$data
分配给隐式变量对我来说似乎有点麻烦。对我来说,这看起来比显式分配给本地化的$\ux更干净-它类似于其他语言中的“with”和类似结构。