我想捕获一连串没有跟随某些数字的数字。例如
input = abcdef lookbehind 123456..... asjdnasdh lookbehind 789432
我想捕获 789432 而不是 123 仅使用负前瞻。
我尝试了 (?<=lookbehind )([\d])+(?!456)
但它捕获了 123456
和 789432
。
使用 (?<=lookbehind )([\d])+?(?!456)
只捕获 1
和 7
。
分组对我来说不是一个选项,因为我的用例不允许我这样做。
有什么方法可以使用纯正则表达式捕获 789432
而不是 123
?
感谢对答案的解释。
最佳答案
你可以使用负向后视的所有格量词
(?<=lookbehind )\d++(?<!456)
^^ ^^^^^^
参见 this regex demo。
具有原子组的同义模式:
(?<=lookbehind )(?>\d+)(?<!456)
详情
-
(?<=lookbehind )
- 正后视匹配字符串中紧接在lookbehind
之前的位置 -
\d++
- 1+ 个数字占有式匹配,不允许回溯到模式中(引擎无法从与\d++
匹配的任何数字重试匹配) -
(?<!456)
- 如果与\d++
匹配的最后 3 位数字是456
,则匹配失败的否定后视检查。
Why lookbehind and why not lookahead
负向回顾 (?<!...)
确保某个模式不会立即匹配到当前位置的左侧。如果它的模式立即匹配到当前位置的右侧,则负先行 (?!...)
将无法匹配。这里的“失败”意味着正则表达式引擎放弃了当前匹配字符串的方式,如果在后视/先行之前有量化模式,引擎可能回溯到这些模式以尝试以不同方式匹配字符串.请注意,这里的所有格量词使引擎无法多次执行 456
的后向检查,只有在 \d++
抓取所有数字后才会执行。
您的 (?<=lookbehind )([\d])+(?!456)
正则表达式匹配 123456
,因为 \d+
以贪婪的方式(一次全部)匹配这些数字,并且 (?!456)
在它们之后检查 456
,并且由于那里没有 456
,因此返回匹配。 (?<=lookbehind )([\d])+?(?!456)
只匹配一个数字,因为\d+?
采用惰性匹配方式,匹配1个数字,然后进行loolahead检查。由于 456
后面没有 1
,所以返回 1
。
why
++
possessive quantifier
如果之前有量化模式,它不允许正则表达式引擎重新尝试以不同方式匹配字符串。因此, (?<=lookbehind )\d+(?<!456)
匹配 12345
中的 123456
,因为 456
之前没有 6
。
关于java - 捕获未跟随某些数字的数字流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50286545/