Perl Regex:匹配这个或那个,但不匹配其他

时间:2014-12-08 16:34:03

标签: regex perl

使用Perl和Regex,是否可以创建单行正则表达式以匹配某些短语而不匹配其他短语?规则存储在散列中,限定符(列)需要匹配表达式。

我有一个对象,其中包含我更喜欢作为单行正则表达式输入的限定符。 例如:

my %filters = {
  rule_a  => {
    regex  => {
      qualifier_a => qr/fruits/i,
      qualifier_b => qr/apples|oranges|!bananas/i, # NOT bananas
    }
  }
}

所以,在这种情况下,我想匹配包含'fruits'和qualifier_b的qualifier_a,其中包含'apples','oranges',但不包含'bananas'。

脚本循环遍历每个限定符,如下所示:

my $match = 1; # Assume a match    
foreach my $qualifier (keys %filters{rule_a}{regex}) {
  # If fails to match, set match as false and break out of loop
  $match = ($qualifier =~ /%filters{rule_a}{regex}{$qualifier}/) ? 1 : 0);
  if(!$match){
   last;
  }
}
if($match){
  # Do all the things
}

思考?

2 个答案:

答案 0 :(得分:3)

有点费解,但是做了它的工作:

^.*?bananas.*(*SKIP)(*FAIL)|apples|oranges

Demo

第一部分将匹配整个字符串(如果它包含bananas),然后强制失败而不在下一个位置重试。

该演示使用.使行独立,但如果您的字符串可以包含换行符,则可以使用s选项。

答案 1 :(得分:1)

您可以使用捕获组并检查其状态:

$match = ($qualifier =~ /banana|(apples|oranges)/);
if (!($match && $1)) {
    last;
}

由于banana不在捕获组中,如果匹配,则不会设置$1

有关此技术的更详细说明,请参阅Regex Pattern to Match, Excluding when... / Except between