与Perl中的变量匹配的两步正则表达式

时间:2011-11-01 16:59:33

标签: regex perl

我希望在Perl中进行两步正则表达式查找,我的文本看起来像这样:

here is some text 9337 more text AA 2214 and some 1190 more BB stuff 8790 words

我还有一个包含以下值的哈希:

%my_hash = ( 9337 => 'AA', 2214 => 'BB', 8790 => 'CC' );

这就是我需要做的事情:

  1. 查找号码
  2. 使用my_hash
  3. 查找号码的文本代码
  4. 检查文本代码是否出现在所标识号码的50个字符内,如果为true,则打印结果
  5. 所以我正在寻找的输出是:

    Found 9337, matches 'AA'
    Found 2214, matches 'BB'
    Found 1190, no matches
    Found 8790, no matches
    

    这是我到目前为止所拥有的:

    while ( $text =~ /(\d+)(.{1,50})/g ) {
      $num = $1;
      $text_after_num = $2;
      $search_for = $my_hash{$num};
      if ( $text_after_num =~ /($search_for)/ ) {
        print "Found $num, matches $search_for\n";
      }
      else {
       print "Found $num, no matches\n";
      }
    

    这种作品,除了唯一正确的匹配是9337;代码与2214不匹配。我认为原因是9337上的正则表达式匹配在第二步匹配的数字之后包含50个字符,然后当正则表达式引擎再次启动时,它从之后的一个点开始。 2214.有一种简单的方法可以解决这个问题吗?我认为\G修饰符可以帮助我,但我不太明白。

    任何建议或帮助都会很棒。

2 个答案:

答案 0 :(得分:3)

你有贪婪的问题。 1,50将尽可能多地消耗。你的正则表达式应该是/(\d+)(.+?)(?=($|\d))/

要解释一下,问号会使多重匹配变得非贪婪(一旦下一个模式匹配就会停止 - 下一个模式优先)。 ?=是一个先行的运算符,用于说“检查下一个元素是否为数字。如果是,则匹配但不消耗。”这允许第一个数字在正则表达式的开头被拾取并被放入下一个匹配的模式。

[编辑] 我向前瞻添加了一个可选的结束值,以便它不会在最后一场比赛中死亡。

答案 1 :(得分:2)

只需使用:

/\b\d+\b/g

如果您不需要,为什么要匹配所有内容?您应该使用其他函数来确定数字的位置:

/(?=9337.{1,50}AA)/

如果AA距离9337的末尾超过50个字符,则会失败。当然,您必须插入您的变量以匹配您的哈希的键和值。这只是您的第一个键/值对的示例。

相关问题