java - 捕获未跟随某些数字的数字流

标签 java regex pattern-matching regex-lookarounds

我想捕获一连串没有跟随某些数字的数字。例如

input = abcdef lookbehind 123456..... asjdnasdh lookbehind 789432

我想捕获 789432 而不是 123 仅使用负前瞻

我尝试了 (?<=lookbehind )([\d])+(?!456) 但它捕获了 123456789432

使用 (?<=lookbehind )([\d])+?(?!456) 只捕获 17

分组对我来说不是一个选项,因为我的用例不允许我这样做。

有什么方法可以使用纯正则表达式捕获 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/

相关文章:

java - 与面向对象方法的斗争

java - GSON:不调用我的解串器

javascript - Ace Editor - 多词高亮规则

c# - 带有 when 子句的 switch 语句的评估顺序是什么?

java - 如果对象 a 和 b 只相互引用,GC 会收集它们吗?

java - Android Studio 可穿戴设备导入 "not working"

regex - 使用 Perl 替换运算符保留捕获

ruby - 如何删除第一个空格或一定数量的字符后的所有内容?

F# 与 for 矩阵匹配

algorithm - 字符串的聚类算法