这是 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 个错误。
我有这个正则表达式:
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 个错误。