当前位置: 首页 > 面试题库 >

正则表达式进入无限循环

胡向阳
2023-03-14
问题内容

我正在解析(种类)表格的名称:

Parus Ater
H. sapiens
T. rex
Tyr. rex

通常有两个项(二项式),但有时有3个或更多。

Troglodytes troglodytes troglodytes 
E. rubecula sensu stricto

我写

[A-Z][a-z]*\.?\s+[a-z][a-z]+(\s*[a-z]+)*

大部分时间都有效,但偶尔会陷入无限循环。花了一些时间来查找正则表达式匹配中的内容,然后我才意识到这是一个错字,我应该写

[A-Z][a-z]*\.?\s+[a-z][a-z]+(\s+[a-z]+)*

正确执行。

我的问题是:

  • 为什么会发生这种循环?
  • 有没有办法在运行程序之前检查类似的正则表达式错误?否则,可能很难在prgram分发之前就将它们捕获并引起问题。

[注意:我不需要物种的更笼统的表达-物种名称有一个正式的100+行正则表达式规范-这只是一个初始过滤器]。

注意:之所以出现此问题,是因为尽管大多数名称被精确地提取为2个或偶而3/4个词(如斜体字),但仍有一些假阳性(如"Homo sapiens lives in big cities like London"),并且匹配在“ L”处失败。]

注意:在调试此程序时,我发现正则表达式经常完成但非常慢(例如,在较短的目标字符串上)。通过病理案例发现此错误很有价值。我学到了重要的一课!


问题答案:

要解决问题的第一部分,您应该阅读灾难性的回溯。本质上,正在发生的事情是有太多方法可以将您的正则表达式与您的字符串进行匹配,并且解析器会不断回溯以尝试使其正常工作。

在您的情况下,可能是嵌套的重新布局: (\s*[a-z]+)*可能导致了一些非常非常奇怪的循环。正如Qtax熟练地指出的那样,没有更多的信息就很难分辨。

不幸的是,问题的第二部分无法回答。基本上是停止问题。由于正则表达式本质上是输入是字符串的有限状态机,因此您无法创建一个通用的解决方案来预测哪些正则表达式将发生灾难性的回退,而哪些不会。

至于使您的正则表达式运行更快的一些技巧?那是一大罐蠕虫。我花了很多时间独自研究正则表达式,并花了一些时间对其进行优化,以下是我发现通常能提供的帮助:

  1. 如果您的语言支持,则在循环之外编译正则表达式。
  2. 只要有可能,就添加锚点。特别是^对于字符串的开头。另请参阅: 字边界
  3. 避免像瘟疫一样嵌套重复。如果需要(必须这样做),请尽力为引擎提供提示,以使任何意外的回溯短路。
  4. 利用风味构造来加快处理速度。我偏爱非捕获组和所有格限定词。它们不会出现在每种口味中,但是当它们出现时,应该使用它们。还要检查原子组
  5. 我总是发现这是对的: 正则表达式获取的时间越长,使它变得高效的麻烦就越大。 正则表达式是一个强大而强大的工具,就像一个超级聪明的锤子。 不要陷入将一切视为钉子的陷阱。有时,您要查找的字符串函数就在您的鼻子下面。

希望对您有帮助。祝好运。



 类似资料:
  • 下面是我正在使用的正则表达式的最新版本,它抛出了错误“Invalid regular expression” XSD:正则表达式在位置4验证失败:当前选项设置不支持此表达式。 我在xsd文件中得到了这个异常,我正在message broker(IIB)中开发这个xsd。有谁能帮我解决这个问题吗?

  • 我想在特殊的符号界之间对一些字符进行分组,但这个界涉及到分组。不与贪婪、勉强量词相连。 结果: 但我料到:

  • 问题内容: 注意:我已经看到了这个问题,但是还没有人回答,所以没有太大帮助。奇怪的是,被标记为“可能重复”的问题已被删除(我第一次看到它。) 我们在使用Pattern进行正则表达式验证时遇到问题。这些都没有发生在我们的代码中,整个事情都在Spring Framework和Hibernate的验证中发生。 (Spring 3.2.1,Spring 3.1.1,Hibernate Validation

  • 昨天,我需要向正则表达式添加一个文件路径,创建一个如下所示的模式: 一开始正则表达式不匹配,因为包含几个正则表达式特定的符号,如 或 。作为快速修复,我将它们替换为 和 . 与 . 然而,我问自己,是否没有一种更可靠或更好的方法来清除正则表达式特定符号中的字符串。 Python 标准库中是否支持此类功能? 如果没有,您是否知道一个正则表达式来识别所有正则表达式并通过替代品清理它们?

  • 在 OpenResty 中,同时存在两套正则表达式规范:Lua 语言的规范和 ngx.re.* 的规范,即使您对 Lua 语言中的规范非常熟悉,我们仍不建议使用 Lua 中的正则表达式。一是因为 Lua 中正则表达式的性能并不如 ngx.re.* 中的正则表达式优秀;二是 Lua 中的正则表达式并不符合 POSIX 规范,而 ngx.re.* 中实现的是标准的 POSIX 规范,后者明显更具备通用

  • 一、概述 二、匹配单个字符 三、匹配一组字符 四、使用元字符 五、重复匹配 六、位置匹配 七、使用子表达式 八、回溯引用 九、前后查找 十、嵌入条件 参考资料 一、概述 正则表达式用于文本内容的查找和替换。 正则表达式内置于其它语言或者软件产品中,它本身不是一种语言或者软件。 正则表达式在线工具 二、匹配单个字符 . 可以用来匹配任何的单个字符,但是在绝大多数实现里面,不能匹配换行符; . 是元字