6

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

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

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

所以:

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

3 回答 3

9

如果您真的需要快速执行此操作,我会查看基于Boyer-Moore string search的想法的自定义搜索。正则表达式被解析为有限状态机。即使是这种 FSM 的巧妙、紧凑的表示也不会是执行您所描述的搜索的非常有效的方法。

如果你真的想继续你现在的路线,你可以连接两个表达式,就像在实践.{30000}.{10000}中一样。.{40000}

于 2012-05-16T19:46:56.063 回答
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;
 }
于 2012-05-16T20:07:47.667 回答
5

40,000 = 2 * 20,000

/d(?:.{20000}){2}o(?:.{20000}){2}g(?:.{20000}){2}s/s
于 2012-05-16T20:57:57.587 回答