【问题标题】:Why does my Perl regex cause an infinite loop?为什么我的 Perl 正则表达式会导致无限循环?
【发布时间】:2009-08-18 21:59:43
【问题描述】:

我有一些代码可以抓取一些文本的“中间”; 具体来说,在foo $someword 和下一个foo $someword 之间。

但是,发生的情况是它卡在第一个“中间”处,并且不知何故内部字符串位置没有增加。

输入数据是一个带有换行符的文本文件:它们无关紧要,但使打印更容易。

my $component = qr'foo (\w+?)\s*?{';

while($text =~ /$component/sg)
{
    push @baz, $1; #grab the $someword
}

my $list = join( "|", @baz);
my $re = qr/$list/; #create a list of $somewords

#Try to grab everything between the foo $somewords; 
# or if there's no $foo someword, grab what's left.

while($text=~/($re)(.+?)foo ($re|\z|\Z)/ms)   
#if I take out s, it doesn't repeat, but nothing gets grabbed.
{
#   print pos($text), "\n";   #this is undef...that's a clue I'm certain.
    print $1, ":", $2; #prints the someword and what was grabbed.
    print "\n", '-' x 20, "\n";
}

【问题讨论】:

  • 你不想在第二个循环中也添加一个“/g”修饰符吗?
  • \z 和 \Z 不是必需的,\Z 包含 \z
  • 我正在浏览文本,而不是抓取数组(这是 /g 将返回的内容)。但是,/g 不会影响最终输出问题。我试过了。 :-)
  • @chas:将其修改为 \Z 并添加 \g 使其循环一次。删除 \g 使其无限循环。

标签: regex perl loops


【解决方案1】:

更新:另一个更新来处理您要提取的文本中出现的'foo'

use strict;
use warnings;

use File::Slurp;

my $text = read_file \*DATA;

my $marker = 'foo';
my $marker_re = qr/$marker\s+\w+\s*?{/;

while ( $text =~ /$marker_re(.+?)($marker_re|\Z)/gs ) {
    print "---\n$1\n";
    pos $text -= length $2;
}

__DATA__
foo one {
one1
one2
one3

foo two
{ two1 two2
two3 two4 }

that was the second one

foo three { 3
foo 3 foo 3
foo 3
foo foo

foo four{}

输出:

--- 一个1 一个2 一个3 --- 二1 二2 二3 二4 } 那是第二个 --- 3 富 3 富 3 富 3 富富 --- }

【讨论】:

  • 关于,是的。我正在寻找 { 之后和下一个 foo 之前的所有内容。
  • 这行得通。如果没有 pos $text -= 3,它将返回第一个和最后一个。恐怕我对为什么您的解决方案有效以及我的解决方案出了什么问题感到很困惑。想法?
  • 寻找(?:foo|\Z) 推进pos $text 的长度foo 如果有一个foo。因此,下一个匹配在下一个foo 之后开始,除非pos $text 重置为下一个foo 之前的位置,即当前位置前三个字符。如果你已经到了字符串的末尾,这没关系。
  • @Sinan:我注意到如果有 my $foomatic,正则表达式匹配“foo”。我修改了我的正则表达式,使其具有 \bfoo\b。 :-) 非常感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-15
  • 1970-01-01
  • 2013-06-17
  • 1970-01-01
  • 1970-01-01
  • 2022-09-24
  • 2011-04-30
相关资源
最近更新 更多