Ach*_*les 6 java regex backtracking
我在我的一个旧Java系统中使用了下面显示的正则表达式,最近导致了回溯问题.回溯线程经常导致机器的CPU达到上限,并且在重新启动应用程序之前它不会返回.
任何人都可以建议一种更好的方法来重写这种模式或一种可以帮助我这样做的工具吗?
图案:
^\[(([\p{N}]*\]\,\[[\p{N}]*)*|[\p{N}]*)\]$
Run Code Online (Sandbox Code Playgroud)
工作价值:
[1234567],[89023432],[124534543],[4564362],[1234543],[12234567],[124567],[1234567],[1234567]
Run Code Online (Sandbox Code Playgroud)
灾难性的回溯值 - 如果值中有任何错误(最后添加额外的括号):
[1234567],[89023432],[124534543],[4564362],[1234543],[12234567],[124567],[1234567],[1234567]]
Run Code Online (Sandbox Code Playgroud)
永远不要用什么*时候+是什么意思.我注意到你的正则表达式的第一件事是几乎所有东西都是可选的.只需要打开和关闭方括号,我很确定您不希望将其[]视为有效输入.
失控回溯的最大原因之一是有两个或更多可以匹配相同事物的替代方案.这就是你所拥有的|[\p{N}]*部分.正则表达式引擎必须在它放弃之前尝试通过字符串的每个可想到的路径,因此所有这些\p{N}*构造都会在每组数字上进行无休止的翻斗.
但尝试修复这些问题毫无意义,因为整体结构是错误的.我想这就是你要找的东西:
^\[\p{N}+\](?:,\[\p{N}+\])*$
Run Code Online (Sandbox Code Playgroud)
在它使用第一个token([1234567])后,如果字符串中的下一个不是逗号或字符串的结尾,它会立即失败.如果它确实看到逗号,它必须继续匹配另一个完整的标记([89023432]),否则它会立即失败.
当你创建一个正则表达式时,这可能是最重要的事情:如果它会失败,你希望它尽快失败.您可以使用原子组和占有量词等功能,但如果正确使用正则表达式的结构,则很少需要它们.回溯并非不可避免.
| 归档时间: |
|
| 查看次数: |
5195 次 |
| 最近记录: |