【问题标题】:Is my regex catastrophically backtracking?我的正则表达式是灾难性的回溯吗?
【发布时间】:2017-07-20 17:30:35
【问题描述】:

我使用正则表达式来验证数字格式。

[-+]?([0-90-9]+((\,([0-90-9]{2,}))*\,([0-90-9]{3}))*)?(\.[0-90-9]*)? 

当我为某些输入处理大量输入时,它似乎无限循环。我阅读了有关灾难性回溯的其他答案。 但我是一个正则表达式新手,需要一些帮助。 您能否提供任何可以使这个正则表达式灾难性地回溯的输入。对我理解会有帮助。谢谢。这也可能是一个很长的输入。 我正在使用 Java 模式和匹配器对象。

【问题讨论】:

  • [0-90-9]可以改成[0-9]
  • 对图案有什么要求? [0-90-9] 当然不是这里的主要问题,而是组内的嵌套量词。
  • 谢谢,我注意到了,但如果有人可以让这个正则表达式无限回溯,我将不胜感激。在这种情况下,我可以确定这就是问题
  • @WiktorStribiżew 给我找一个会破坏这个正则表达式的输入,即导致它无限循环
  • 这与“无限循环”“递归回溯”无关...

标签: java regex infinite-loop matcher recursive-backtracking


【解决方案1】:

要验证您的输入字符串,请使用这个:

^[-+]?(\d+((\,(\d{2,}))*\,(\d{3}))*)?(\.\d*)?$

正如我在 cmets 中所写:

您所有的捕获组都是可选的,其中使用?*,如果您想验证输入,请添加^...$ 包装器

查看标题为MATCH INFORMATION

https://regex101.com/r/eM7OFj/1右侧栏

【讨论】:

  • 谢谢,我知道可以将模式更改为更好的模式,但我想知道任何可能导致此模式无限期运行的示例输入。
  • 您的模式针对输入文本中的每个字符运行。注意使用^$
  • Test your regex 有 16 个匹配的空字符串 @SainathS.R
【解决方案2】:

是的,这个正则表达式很容易发生灾难性的回溯。具体来说,这部分:

((\,([0-9]{2,}))*\,([0-9]{3}))*

作为参考,它具有以下形式的结构

((,d)*,d)*

简化后基本上是(d+)*

类似的字符串

1,111,111,111,111,111,111,111,111,111,111,111,111,111,11.

因此会导致灾难性的回溯。

【讨论】:

  • 那个字符串运行良好:(
  • 请注意,这只是锚定上下文中的问题,例如.matches
  • @SainathS.R 然后让它更长。
  • @SebastianProske 你能详细说明一下吗?
  • @Rawing 我做了很长时间,仍然在合理的时间内终止
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-24
  • 2020-12-23
  • 2021-12-19
  • 2017-09-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多