这是 ruby 正则表达式中的错误吗?如何在不使用超时的情况下防止来自正则表达式匹配的 "infinite loop"?

Is this a bug in ruby Regexp? How to guard against "infinite loop" from regex match without using Timeout?

我有这个正则表达式:

regex = /(Si.ges[a-zA-Z\W]*avec\W*fonction\W*m.moires)/i

当我在一些但不是全部的文本上使用它时,例如这个:

text = "xation de 2 sièges-enfants sur la banquette AR),Pack \"Assistance\",Keyless Access avec alarme : Système de verrouillage/déverrouillage et de démarrage sans clé,Park Assist: Système d'assistance au stationnement en créneauet et en bataille,Rear Assist: Caméra de recul avec visualisation de la zone situ"

像这样:text.match(regex),然后 ruby 就好像在无限循环中运行 - 但为什么呢?无论如何要防止这种情况,例如通过让 ruby 抛出异常 - 不使用 Timeout 因为这是与 Sidekiq (https://github.com/mperham/sidekiq/wiki/Problems-and-Troubleshooting#add-timeouts-to-everything)

一起使用时的已知问题

ruby版本:2.7.2

Built-in字符class更多table-driven.
鉴于此,负面 built-in 像 \W\S 等...
引擎很难合并成正字符 class.

在这种情况下,存在一些明显的错误,因为正如您所说,它不会超时
一些目标字符串。

事实上,[a-xzA-XZ\W] 可以在给定示例字符串的情况下工作。当 Y 包含在任何地方
时超时 但只是针对那个特定的字符串。

让我们看看是否可以确定这是否是错误。

首先,一些测试:

测试 - 失败 [a-zA-Z\W]

https://rextester.com/FHUQG84843

# Test - Fail  [a-zA-Z\W]
puts "Hello World!";
regex = /(Si.ges[a-zA-Z\W]*avec\W*fonction\W*m.moires)/ui;
text = "xation de 2 sièges-enfants sur la banquette AR),Pack \"Assistance\",Keyless Access avec alarme : Système de verrouillage/déverrouillage et de démarrage sans clé,Park Assist: Système d'assistance au stationnement en créneauet et en bataille,Rear Assist: Caméra de recul avec visualisation de la zone situ";
res = text.match(regex);
puts "Done";

测试 - 通过 [a-xzA-XZ\W]

https://rextester.com/RPV28606

测试 - 通过 [a-zA-Z\P{Word}]

https://rextester.com/DAMW9069


结论:将此作为 BUG 报告。
IMO 这是一个 BUG,它们的 built-in class \W 是引擎定义的,
因为 \P{Word} 是 Unicode 属性 定义的函数,而不是范围。
我们看到 [a-zA-Z\P{Word}] 工作得很好。
在 classes 中使用 \P{Word} 作为临时解决方法。

实际上,当 modern-day 引擎最初设计时,
的逻辑是什么 负数 class 是 [^] 每个项目与正数
组合时是 AND NOT class 其中每个项目的 ORed 导致范围错误。
不久前,Perl 还存在 class 个错误。