【问题标题】:Why my Python regular expression pattern run so slowly?为什么我的 Python 正则表达式模式运行如此缓慢?
【发布时间】:2015-02-11 10:23:48
【问题描述】:

请看我的正则表达式模式代码:

#!/usr/bin/env python
# -*- coding:utf-8 -*-

import re

print 'Start'
str1 = 'abcdefgasdsdfswossdfasdaef'
m = re.match(r"([A-Za-z\-\s\:\.]+)+(\d+)\w+", str1) # Want to match something like 'Moto 360x'
print m # None is expected.
print 'Done'

完成需要49秒,图案有问题吗?

【问题讨论】:

  • ([A-Za-z\-\s\:\.]+)+ --> [A-Za-z\-\s\:\.]+
  • 因为您的正则表达式可以通过无数种不同的方式匹配字符串,并且引擎正在回溯并尝试每种变体。
  • 更多关于正则表达式回溯的原因和原因以及当你不匹配时它会变得多么灾难性的更多信息:regular-expressions.info/catastrophic.html

标签: python regex


【解决方案1】:

Runaway Regular Expressions: Catastrophic Backtracking

简而言之,如果有非常多的组合可以将子字符串拆分为正则表达式的各个部分,则正则表达式匹配器最终可能会尝试所有组合。

(x+)+x+x+ 这样的构造实际上保证了这种行为。

要检测和修复有问题的结构,可以使用以下概念:

  • 在概念层面,存在问题的构造意味着您的正则表达式是模棱两可的 - 即如果您无视贪婪/懒惰的行为,则没有将某些文本单独“正确”拆分为正则表达式的部分(或等效地,其子表达式)。因此,要避免/解决问题,您需要查看并消除所有歧义。

    • 一种方法是

      • 始终将文本拆分为有意义的部分(=对于手头的任务具有不同含义的部分),并且
      • 以不会混淆的方式定义各个部分(=使用与您自己相同的特征,如果您手动解析它,您会用来分辨哪个是哪个)

【讨论】:

  • (x+y)+ 形式的东西是否同样危险,还是不太可能成为问题?
  • @jpmc26 除非某些东西同时匹配xyy 可以是x 之间的空白匹配。
  • 另外值得注意的是,这不是正则表达式的固有问题,而是许多常见正则表达式库中的设计决策造成的问题。 RE2 引擎没有这个问题。
  • @thatotherguy 你给出的例子是the other approach to matching: text-directed。它确实避免了这个问题,但它不能使用一些特性,比如惰性量词或反向引用。
【解决方案2】:

只需在 nhahtdh 和 Marc B 的 cmets 中重新发布答案和解决方案:

([A-Za-z\-\s\:\.]+)+ --> [A-Za-z\-\s\:\.]+

非常感谢 nhahtdh 和 Marc B!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-14
    • 2011-03-08
    • 2012-06-30
    • 2019-03-12
    • 2018-05-08
    • 1970-01-01
    相关资源
    最近更新 更多