表达式中多个连续的 .* 导致匹配缓慢

Multiple consecutive .* in expression lead to slow matching

我注意到如果我使用正则表达式 .*.*text.*.*,匹配比在 .*text.*

上匹配花费的时间长得多

您可能已经猜到,带有双 .*.* 的正则表达式是由软件(意外地)生成的。

接下来有 ​​2 个问题:

  1. 我打算在 运行 匹配之前用 .* 替换 .*.*。我总是可以用 .* 替换 .*.* 吗?是否存在 .*.* 在正则表达式中在功能上不等于 .* 的情况?

  2. 谁能用简单的方式解释为什么匹配 .*.* 需要这么长时间?

如果这是特定于实现的行为,我正在使用 Java 7 的正则表达式引擎。

在比赛中 .*.* 等同于 .*。在性能方面,您将节省大量时间。你应该学习回溯。

你可以看到 .*.*Donec.*.* and .*Donec.* 之间的步数从 101 897 到只有 604 反对前两段Lorem Ipsum.

两个正则表达式 .*.*.* 在数学上是绝对相等的。如果它们不以相同的速度匹配是由于编译和匹配时使用的实现。

如果你使用一个好的正则表达式编译器,你会得到一次通过,没有回溯算法,只探索匹配字符串的每个字符一次,处理 O[n] 算法,独立于您使用的正则表达式。

顺便说一句,绝大多数语言(perl、java、php等)中使用的所有当前实现都来自有限 NFA(非确定性有限)的直接解释自动机)在匹配器字符串上。但是,如果您阅读 Compilers, Principles, Techniques and Tools 中描述的算法,您会发现只需访问每个字符一次(并按顺序)即可获得匹配项