Perl:“在{,}中的量词大于正则表达式中的32766”

时间:2012-05-16 19:40:33

标签: regex perl

假设我想找一个大的(300,000个字母)单词“dogs”,字母之间的距离正好 40,000个字母。所以我这样做:

$mystring =~ m/d.{40000}o.{40000}g.{40000}s/;

这在其他(较慢的)语言中会很好用,但在Perl中它会让我“在{,}中的量词大于正则表达式中的32766”。

所以:

  1. 我们可以以某种方式使用更大的数字作为量词吗?
  2. 如果没有,还有另一种好方法可以找到我想要的东西吗?请注意,“狗”只是一个例子;我想为任何单词和任何跳转大小(和快速)执行此操作。

3 个答案:

答案 0 :(得分:9)

如果您确实需要快速,我会根据Boyer-Moore string search的想法查看自定义搜索。正则表达式被解析为有限状态机。即使是这种FSM的巧妙,紧凑的表示也不会像你描述的那样执行搜索。

如果你真的想继续沿着这条线前进,你可以连接两个像.{30000}.{10000}这样的表达式,这在实践中与.{40000}相同。

答案 1 :(得分:5)

我认为index可能更适合这项任务。完全未经测试的东西:

sub has_dogs {
    my $str = shift;
    my $start = 0

    while (-1 < (my $pos = index $$str, 'd', $start)) {
        no warnings 'uninitialized';
        if ( ('o' eq substr($$str, $pos +  40_000, 1)) and
             ('g' eq substr($$str, $pos +  80_000, 1)) and
             ('s' eq substr($$str, $pos + 120_000, 1)) ) {
             return 1;
         }
     }
     return;
 }

答案 2 :(得分:5)

40,000 = 2 * 20,000

/d(?:.{20000}){2}o(?:.{20000}){2}g(?:.{20000}){2}s/s