【问题标题】:Computational complexity for regular expressions正则表达式的计算复杂度
【发布时间】:2019-07-08 14:17:14
【问题描述】:

正则表达式很快变得太复杂(对我来说)难以理解。即使像[ab][cd] 这样简单的东西,也有几个逻辑分支。我的目标是提高代码库的可维护性,因此这些问题的答案可以帮助我们检测和修复复杂代码:

  1. 是否存在计算复杂度度量(类似于圈复杂度),包括 正则表达式固有的复杂性?
  2. 有什么工具吗 产生正则表达式的复杂度数?
  3. 是否有工具可以建议简化正则表达式?

【问题讨论】:

  • 复杂度指标?是的,只要您看到类似于((x*)*)*(嵌套量化模式)的模式,它就很复杂。

标签: regex language-agnostic code-metrics cyclomatic-complexity code-maintainability


【解决方案1】:

您可以尝试使用正则表达式的编译形式,并尝试将一些代码复杂度指标映射到该形式,例如代码行数或圈复杂度。要了解我的意思,请查看以下 stackoverflow 答案:https://stackoverflow.com/a/2348725/5747415,它显示了如何使用 perl 访问正则表达式的编译形式。此处显示了另一个示例:http://perldoc.perl.org/perldebguts.html#Debugging-Regular-Expressions,引用了该页面的工具输出:

Compiling REx '[bc]d(ef*g)+h[ij]k$'
1: ANYOF[bc](12)
12: EXACT <d>(14)
14: CURLYX[0] {1,32767}(28)
16:   OPEN1(18)
18:     EXACT <e>(20)
20:     STAR(23)
21:       EXACT <f>(0)
23:     EXACT <g>(25)
25:   CLOSE1(27)
27:   WHILEM[1/1](0)
28: NOTHING(29)
29: EXACT <h>(31)
31: ANYOF[ij](42)
42: EXACT <k>(44)
44: EOL(45)
45: END(0)

顺便说一句,我祝贺您决定提高代码的可维护性。也就是说,我只需要表达我的怀疑,即任何正式的指标都比(甚至可以接近)有经验的开发人员的判断提供更好的指导......

【讨论】:

  • 您说得对,许多软件指标都过于简单化了。但是,它们有助于识别潜在的问题点,尤其是在大型代码库中。
【解决方案2】:

如果您正在处理与正式正则表达式等效的正则表达式系统(描述正则语言;不计数、不向后查找、不匹配括号对等),或者如果您只处理正则表达式它使用这些功能(尽管您的正则表达式系统能够描述非常规语言),那么就有一个精确的复杂性概念(或者至少您可以推导出一个),并且在某种意义上可以“最小化”正则表达式”。

根据 Myhill-Nerode 定理,所有常规语言在字符串的不可区分关系下都有有限数量的等价类。这些等价类直接对应于常规语言的最小确定性有限自动机中的状态。您可以将语言的最小确定性有限自动机的状态数视为语言本身的“基本”复杂性。

有些算法可以将您从(正式的)正则表达式带到最小确定性有限自动机,然后再回到正则表达式。这样做应该为您提供每种常规语言的规范正则表达式。我想——但还没有证明——可以修改从最小确定性有限自动机生成正则表达式的过程,以便它生成可能的缩短(就操作数而言)正则表达式。

语言的复杂性可能是这样一个规范的正则表达式中的操作数。任何给定正则表达式的实际复杂性可能是其中的操作数。该比率可以让您了解您的正则表达式是多么“低效”或“不必要地复杂”。

如果你真的需要正则表达式的非常规特性,那么你就不走运了;在高阶语言类中没有可计算最小化的概念。你可以整天发明复杂性指标,但你永远不会得到一个通用的算法答案来回答“与基线相比,这有多低效?”我的意思的另一种说法是:做蛋糕可能比做爆米花更难,但如果你需要蛋糕,就必须付出额外的努力才能得到你需要的东西。

【讨论】:

  • 经过反思,从最小确定性有限自动机得到的正则表达式不会是最小的;正则表达式更接近于非确定性有限自动机,它可以小于相应的最小确定性自动机。这并没有太大变化,除了您的比率可能小于一(如果您的正则表达式依赖于非确定性来更简洁地描述语言而不是纯粹确定性地描述语言)。否则,该过程的工作方式相同。
猜你喜欢
  • 2019-04-30
  • 1970-01-01
  • 2015-02-21
  • 2019-08-30
  • 1970-01-01
  • 2021-07-08
  • 1970-01-01
  • 1970-01-01
  • 2011-08-19
相关资源
最近更新 更多