Regex引擎如何为正则表达式生成NFA?

时间:2018-03-27 03:13:00

标签: regex nfa

在此Wiki页面中:https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS#The_problematic_Regex_na.C3.AFve_algorithm

你可以看到正则表达式^(a+)+$

创建了以下NFA:

enter image description here

我的问题是:从正则表达式创建此NFA的过程是什么?

1 个答案:

答案 0 :(得分:3)

他们没有。

大多数正则表达式引擎都不会创建NFA,而是通过回溯来工作。
回溯是一个重新访问你所做的每一个决定,撤消它,并尝试另一个选项直到某些东西工作的过程,这很快就会变得低效。发动机通常不够智能以消除类似的路径,某些模式的性能可能成为指数。

可以在Runaway Regular Expressions: Catastrophic Backtracking中找到一个很好的解释 在^(a+)+$输入aaaaaaaaaaaaX的示例中,引擎会尝试所有组合:

  • aaaaaaaaaaaa
  • aaaaaaaaaaa a
  • aaaaaaaaaa aa
  • aaaaaaaaaa a a
  • ...
  • aa aaaaaaaaaa
  • a aaaaaaaaaaa
  • ...
  • a a aaaa aaaa aa

......这很多。

您所关联的OWASP文章正在展示真正的拒绝服务攻击,但解释纯粹是理论上的 - 这不是攻击的实际工作方式。

匹配正则表达式可以更好地实现:关于该主题的规范性文章是Regular Expression Matching Can Be Simple And Fast (but is slow in Java, Perl, PHP, Python, Ruby, ...),其中还包含您的问题的答案,解释了如何有效地构建正确的NFA和匹配模式。

采用这种方法的一个引擎是RE2的正则表达式库。 RE2确实构建了NFA,其性能总体上要好得多,但需要权衡:RE2 does not have common features like lookarounds and back-references
例如,RE2 can quickly discover there is no match on ^(((a+)+)+)+$,而other flavors time out

另见: