可变长度 Lookbehind 在 perl 文件中不起作用,但在单行中起作用

Variable-Length Lookbehind not work in perl file, but work in one-liner

如果我把 s/(?<!(?:href|src)=.{0,40})jpg//g 放在一个 perl 文件中,并尝试 运行 它,它会给出警告: Variable length lookbehind is experimental in regex; marked by 并失败。

但是如果放在一个 perl 单行代码中,它将 运行 成功,尽管仍然会被警告 Variable length lookbehind is experimental in regex; marked by

是目前的设计还是我用错了?

更新:我正在使用 perl 5.31.3

在 v5.30 之前,具有不确定的“可变宽度”模式的正后视无法编译并出现 Variable length lookbehind not implemented 错误。

在 v5.30 中,您are allowed使用最多可以匹配 255 个字符的后视模式。

Using a lookbehind assertion (like (?<=foo?) or (?<!ba{1,9}r) previously would generate an error and refuse to compile. Now it compiles (if the maximum lookbehind is at most 255 characters), but raises a warning in the new experimental::vlb warnings category. This is to caution you that the precise behavior is subject to change based on feedback from use in the field.

如果你使用 (?<=WORD\s+),你会得到一个 Lookbehind longer than 255 not implemented 错误,因为正则表达式引擎需要提前知道子模式的长度' 长于 255,并且 + 量词的长度不确定。所以,(?<=WORD\s{0,255}) 会起作用。

在你的情况下,你知道你的后视模式永远不会匹配超过 255 个字符,所以只需像任何其他实验性警告一样转动该实验性警告:

no warnings qw(experimental::vlb);

注意:确保将上面的行放在 之后 use warnings; 行(如果存在),否则它将没有持久效果,被 [= 覆盖19=].

Perl 不关心代码是通过 -e 还是文件提供的。代码在这两种情况下的行为相同。它失败的原因不是因为您使用了发布在文件中而不是命令行中的代码。您还没有发现导致行为差异的另一个差异。


那是说您不应该使用您发布的费用。正如警告大声宣布的那样,这是一个 实验性功能 。它未经证实,因此可能存在问题。此外,它如有更改和删除,恕不另行通知。

您可以使用以下替代方法来消除对实验性 variable-length 回顾的使用:

s/(?:href|src).{0,40}(*SKIP)(*FAIL)|jpg//g

(*FAIL)导致模式不匹配,从而触发回溯。但是 (*SKIP) 让它在以后的尝试中从 (?:href|src).{0,40} 匹配的字符串之后的位置开始匹配。