简体   繁体   中英

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

If I put s/(?<!(?:href|src)=.{0,40})jpg//g in a perl file, and try to run it, it will give the warning: Variable length lookbehind is experimental in regex; marked by Variable length lookbehind is experimental in regex; marked by and fail.

But if put in a perl one-liner, it will run successfully, although still be warned of Variable length lookbehind is experimental in regex; marked by Variable length lookbehind is experimental in regex; marked by .

Is it by current design or maybe I'm using it wrong?

Update: I'm using perl 5.31.3

Before v5.30, a positive lookbehind with indeterminate, "variable width" pattern fails to compile with the Variable length lookbehind not implemented error.

In v5.30, you are allowed to use a lookbehind pattern that can match up to 255 chars.

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.

If you use (?<=WORD\\s+) , you will get a Lookbehind longer than 255 not implemented error since the regex engine needs to know in advance that the length of the subpattern won't be longer than 255 and the + quantifier has an indeterminate length. So, (?<=WORD\\s{0,255}) would work.

In your case, you know your lookbehind pattern will never match more than 255 chars, so just turn that experimental warning like any other experimental warnings:

no warnings qw(experimental::vlb);

Note: Make sure that the above line is placed after the use warnings; line, if present, or it will have no lasting effect, being overridden by use warnings; .

Perl doesn't care if the code is provided via -e or via a file. The code behaves identically in both situations. The reason it fails is not because you used the code you posted in a file instead of on the command line. There is another difference you haven't identified causing the difference in behaviour.


That said you shouldn't use the cost you posted. As the warning loudly announces, this is an experimental feature . It is unproven, and thus potentially problematic. Also, it is subject to change and removal without further notice.

You can eliminate the use of the experimental variable-length lookbehind by using the following instead:

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

(*FAIL) causes the pattern not to match, and thus trigger backtracking. But (*SKIP) made it so that it will start matching at the position after the string matched by (?:href|src).{0,40} in future attempts.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM