在某些情况下,Python Regex需要很长时间

时间:2014-03-05 18:19:54

标签: python regex

我编译了以下模式

pattern = re.compile(
    r"""
    (?P<date>.*?)
    \s*
    (?P<thread_id>\w+)
    \s*PACKET\s*
    (?P<identifier>\w+)
    \s*
    (?P<proto>\w+)
    \s*
    (?P<indicator>\w+)
    \s*
    (?P<ip>\d+\.\d+\.\d+\.\d+)
    \s*
    (?P<xid>\w+)
    \s*
    (?P<q_r>.*?)
    \s*\[
    (?P<flag_hex>[0-9]*)
    \s*
    (?P<flag_char_code>.*?)
    \s*
    (?P<status>\w+)
    \]\s*
    (?P<record>\w+)
    \s*
    \.(?P<domain>.*)\.
    """, re.VERBOSE
    )

使用此字符串

2/1/2014 9:34:29 PM 05EC PACKET 00000000025E97A0 UDP Snd 10.10.10.10 ebbe R Q [8381 DR NXDOMAIN] A (1)9(1)a(3)c-0(11)19-330ff801(7)e0400b1(4)15e0(4)1ca7(4)2f4a(3)210(1)0(26)841f75qnhp97z6jknf946qwfm5(4)avts(6)domain(3)com(0)

它成功运作

In [4]: pattern.findall(re.sub('\(\d+\)', '.', x))
Out[4]: 
[('2/1/2014 9:34:29 PM',
  '05EC',
  '00000000025E97A0',
  'UDP',
  'Snd',
  '10.10.10.10',
  'ebbe',
  'R Q',
  '8381',
  'DR',
  'NXDOMAIN',
  'A',
  '9.a.c-0.19-330ff801.e0400b1.15e0.1ca7.2f4a.210.0.841f75qnhp97z6jknf946qwfm5.avts.domain.com')]

问题是在某些情况下需要很长时间,任何想法如何增强模式以消耗时间。

2 个答案:

答案 0 :(得分:6)

是的,你有catastrophic backtracking的情况,也被称为“邪恶正则表达”,在这里:

\s*
(?P<q_r>.*?)
\s*

下面:

\s*
(?P<flag_char_code>.*?)
\s*

在这里:

\s*
\.(?P<domain>.*)\.

.*替换\S*应该可以解决问题。

有关邪恶的正则表达是什么以及为什么它是邪恶的更多信息,请查看这个问题:
How can I recognize an evil regex?

答案 1 :(得分:1)

您可以通过以下方式改善模式:

(?P<domain>\w+(?:[-.]\w+)*)
(?P<date>\d{1,2}/\d{1,2}/\d{4} \d{1,2}:\d{1,2}:\d{1,2} [AP]M)
(?P<q_r>[^[]*)

您还需要为flag_char_code提供更明确的子模式,目标是描述每个组的内容以减少正则表达式引擎的工作并避免回溯。