Perl未能说明“可变长度后备未实现”

时间:2013-11-20 18:38:35

标签: regex perl

我基本上是在做一种单词边界断言。我想测试[abc]是否落后,[abc]是否提前,反之亦然。

所以我试着对它进行测试并做出这样的否定:

#!/usr/bin/perl
($_) = "abcdef" =~
/
((?&BB).*)
|
  (?!)
  (?<W>[abc])
  (?<NW>[^abc])
  (?<BB>
     (?<=(?&W))(?=(?&NW))
    |(?<=(?&NW))(?=(?&W))
  )
/x;
print;

哪个不起作用。但是,如果我这样做:

#!/usr/bin/perl
($_) = "abcdef" =~
/
  ((?&BB).*)
| (?!)
  (?<W>[abc])
  (?<NW>[^abc])
  (?<BB>
      (?<=[abc])(?=[^abc])
    | (?<=[^abc])(?=[abc])
  )
/x;
print;

确实如此。这里发生了什么?可变长度看起来在哪里?

仅供参考,我知道这个消息意味着什么。我想知道为什么perl认为命名组的长度可变,我怎么能让它停止思考呢?对我来说,这看起来像是一个错误。其他人同意吗?

使用版本:

This is perl 5, version 14, subversion 4 (v5.14.4) built for cygwin-thread-multi
This is perl 5, version 16, subversion 2 (v5.16.2) built for i686-linux

修改

所以我找到了一个足够的工作。

#!/usr/bin/perl
$chars = qr/[abc]/;
$notChars = qr[^abc]/;
($_) = "abcdef" =~
/
  ((?&BB).*)
| (?!)
  (?<BB>
      (?<=$chars)(?=$notChars)
    | (?<=$notChars)(?=$chars)
  )
/x;
print;

4 个答案:

答案 0 :(得分:7)

lookbehind节点只是查看它的子节点,看到它包含一个命名的子规则匹配,并确定一个命名的子规则匹配不一定是固定长度的。它没有查看命名子规则内部以发现它实际上确实具有固定长度,并且我不确定它是否可以给出代码的当前状态。由于它无法确定固定长度,因此无法编译后备。

也许该消息应该与Can't determine the length of '(?&W)' for use in lookbehind而不是Variable length lookbehind not implemented一致。

答案 1 :(得分:1)

看起来就在这里:

(?<=(?&W))(?=(?&NW))
    |(?<=(?&NW))(?=(?&W))

在Perl 5中,正则表达式不支持查找可变数量的捕获(()中的内容)。

&lt; =以及()中的任何内容都是lookbehind语法的所在。

编辑:下面的评论可以澄清问题。

看起来你拥有的变量长度是你拥有[^ abc]命名模式的事实所固有的,它有很多可以返回的匹配长度。可变长度来自这样一个事实:任何长度的文本都可以匹配!abc。

的字符类

Perl 6似乎以某种方式支持这一点。

有关此问题,请参阅Perl 6的RFC链接 http://perl6.org/archive/rfc/72.html

答案 2 :(得分:1)

命名捕获的匹配并不总是固定长度,这就是正则表达式引擎不允许在后台进行反向引用的原因。名为capture的可变长度示例:

/(?|a(?<toto>ef)|b(?<toto>ghi))/

答案 3 :(得分:1)

对我来说看起来像个错误,但错误的解决方法可能只是有一个单独的错误消息“Recursive capture group lookbehind not implemented”:))