Quantifier range not working in lookbehind

牧云@^-^@ 提交于 2020-01-02 05:05:29

问题


Okay so I'm working on a project where I need a regex that can match a * followed by 1-4 spaces or tabs and then followed by a row of text. Right now I'm using .* after the lookbehind for testing purposes. However I can get it to match explicitly 1, 2, or 4 spaces/tabs but not 1-4. I'm testing against the following block

*    test line here
*   Second test
*  Third test
* Another test

And these are the two patterns I'm testing (?<=(\*[ \t]{3})).* which works just as expected and matches the 2nd line, same if I replace 3 with 1, 2 or 4 however if I replace it with 1,4 forming the following pattern (?<=(\*[ \t]{1,4})).* it no longer matches any of the rows and I honestly can't understand why. I've tried googling without success. I'm using the g(lobal) flag.


回答1:


PHP, like many flavors, doesn't support variable length lookbehind. The only support is alternation (|) at the top level of the lookbehind. Even a ? can break the pattern. An alternative is to use:

(?<=\*[ \t]|\*[ \t]{2}|\*[ \t]{3}|\*[ \t]{4}).*

Or better, abort the lookbehind for a group:

\*[ \t]{1,4}(.*)

This should work well for you, since it doesn't seem like you have overlapping of your matches anyway.

From the manual:

The contents of a lookbehind assertion are restricted such that all the strings it matches must have a fixed length. However, if there are several alternatives, they do not all have to have the same fixed length. Thus (?<=bullock|donkey) is permitted, but (?<!dogs?|cats?) causes an error at compile time. Branches that match different length strings are permitted only at the top level of a lookbehind assertion.

Source: http://www.php.net/manual/en/regexp.reference.assertions.php



来源:https://stackoverflow.com/questions/4956360/quantifier-range-not-working-in-lookbehind

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!