当前位置:  开发笔记 > 编程语言 > 正文

正则表达式'|' 运算符vs每个子表达式的单独运行

如何解决《正则表达式'|'运算符vs每个子表达式的单独运行》经验,为你挑选了2个好方法。

我有一个相当大的字符串(~700k),我需要运行10个正则表达式并计算任何正则表达式的所有匹配项.我的快速和肮脏的impl是做一些像re.search('(expr1)|(expr2)| ...'),但我想知道我们是否通过循环匹配看到任何性能提升:

换句话说,我想比较以下的表现:

def CountMatchesInBigstring(bigstring, my_regexes):
  """Counts how many of the expressions in my_regexes match bigstring."""
  count = 0
  combined_expr = '|'.join(['(%s)' % r for r in my_regexes])
  matches = re.search(combined_expr, bigstring)
  if matches:
    count += NumMatches(matches)
  return count

VS

def CountMatchesInBigstring(bigstring, my_regexes):
  """Counts how many of the expressions in my_regexes match bigstring."""
  count = 0
  for reg in my_regexes:
    matches = re.search(reg, bigstring)
    if matches:
      count += NumMatches(matches)
  return count

我将不再懒惰并明天进行一些测试(并发布结果),但我想知道答案是否会跳到真正了解正则表达式如何工作的人身上:)



1> Nick Fortesc..:

除非保证匹配只匹配一个正则表达式,否则这两个结果会略有不同.否则如果匹配2,它将被计数两次.

理论上你的解决方案应该更快(如果表达式是互斥的),因为正则表达式编译器应该能够创建一个更有效的搜索状态机,因此只需要一次传递.我希望差异很小,除非表达非常相似.

此外,如果它是一个巨大的字符串(大于700k),那么进行一次传递可能会有所收获,因此需要更少的内存交换(磁盘或cpu缓存).

我打赌你的测试虽然不是很明显.我对实际结果感兴趣 - 请发布结果.



2> Mykola Khare..:

要了解re模块的工作原理 - 在调试模式下编译_sre.c(在_sre.c中将#define VERBOSE放在103行并重新编译python).在此之后你会看到这样的事情:


>>> import re
>>> p = re.compile('(a)|(b)|(c)')
>>> p.search('a'); print '\n\n'; p.search('b')
|0xb7f9ab10|(nil)|SEARCH
prefix = (nil) 0 0
charset = (nil)
|0xb7f9ab1a|0xb7fb75f4|SEARCH
|0xb7f9ab1a|0xb7fb75f4|ENTER
allocating sre_match_context in 0 (32)
allocate/grow stack 1064
|0xb7f9ab1c|0xb7fb75f4|BRANCH
allocating sre_match_context in 32 (32)
|0xb7f9ab20|0xb7fb75f4|MARK 0
|0xb7f9ab24|0xb7fb75f4|LITERAL 97
|0xb7f9ab28|0xb7fb75f5|MARK 1
|0xb7f9ab2c|0xb7fb75f5|JUMP 20
|0xb7f9ab56|0xb7fb75f5|SUCCESS
discard data from 32 (32)
looking up sre_match_context at 0
|0xb7f9ab1c|0xb7fb75f4|JUMP_BRANCH
discard data from 0 (32)
|0xb7f9ab10|0xb7fb75f5|END




|0xb7f9ab10|(nil)|SEARCH
prefix = (nil) 0 0
charset = (nil)
|0xb7f9ab1a|0xb7fb7614|SEARCH
|0xb7f9ab1a|0xb7fb7614|ENTER
allocating sre_match_context in 0 (32)
allocate/grow stack 1064
|0xb7f9ab1c|0xb7fb7614|BRANCH
allocating sre_match_context in 32 (32)
|0xb7f9ab20|0xb7fb7614|MARK 0
|0xb7f9ab24|0xb7fb7614|LITERAL 97
discard data from 32 (32)
looking up sre_match_context at 0
|0xb7f9ab1c|0xb7fb7614|JUMP_BRANCH
allocating sre_match_context in 32 (32)
|0xb7f9ab32|0xb7fb7614|MARK 2
|0xb7f9ab36|0xb7fb7614|LITERAL 98
|0xb7f9ab3a|0xb7fb7615|MARK 3
|0xb7f9ab3e|0xb7fb7615|JUMP 11
|0xb7f9ab56|0xb7fb7615|SUCCESS
discard data from 32 (32)
looking up sre_match_context at 0
|0xb7f9ab2e|0xb7fb7614|JUMP_BRANCH
discard data from 0 (32)
|0xb7f9ab10|0xb7fb7615|END

>>>                                      

推荐阅读
ar_wen2402851455
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有