几千字的python正则表达式

时间:2011-06-08 09:39:26

标签: python regex pattern-matching

我正在尝试使用python在字符串中查找某些关键字。字符串是这样的:

A was changed from B to C

所有我试图找到的是“到C”部分,其中 C是千言万语之一

此代码构建regexp字符串:

pre_pad = 'to '
regex_string = None
for i in words:
    if regex_string == None:
        regex_string = '\\b%s%s(?!-)(?!_)\\b' %(pre_pad, i)
    else:
        regex_string = regex_string + '|\\b%s%s(?!-)(?!_)\\b' %(pre_pad, i)

后来我做了:

matches = []
for match in re.finditer(r"%s" %regex_string, text):
        matches.append([match, MATCH_TYPE])

此代码适用于Linux,但在macos上崩溃, “渲染时出现Caught OverflowError:超出正则表达式代码大小限制”

我意识到regex_string非常长并且这是问题的原因

print regex_string.__len__()
63574

我该如何解决这个问题,以便它始终有效,与单词的数量无关?

修改

我忘了提到pre_pad有时是空的:pre_pad ='',因此首先不可能首先搜索pre_pad。

除此之外,我首先构建整个regex_string然后将它与单词匹配的原因是我必须对数千个条目进行匹配。如果我每次都必须再次构建regex_string,这将导致性能非常差。

哦,我需要知道哪个词匹配。

5 个答案:

答案 0 :(得分:3)

这不应该是一个你可以用巨大的正则表达式解决的任务,并期望比这更好的表现:

pre_pad = 'to '
matches = []

for i in words:
    regex_string = '\\b%s%s(?!-)(?!_)\\b' % (pre_pad, i)
    for match in re.finditer(r"%s" % regex_string, text):
        matches.append([match, MATCH_TYPE])

此外,如果在分析之后你看到链式正则表达式工作更快,那么在构建它时计算你的正则表达式字符串长度并将完整任务拆分为2,3,10以避免溢出。

P.S:

print len(regex_string)

更pythonic ......

答案 1 :(得分:1)

您可以通过简单的正则表达式从输入中提取C,然后在针对搜索优化的结构中查找:

  • 一些树
  • 带二进制搜索的有序列表
  • 哈希结构(如python的set

这样的东西
return match_from_regex in set_of_words

答案 2 :(得分:1)

说实话,我会稍微改变一下这个问题。我会制作一个单词地图(我可以检查这个单词是否存在O(1)复杂度)。然后搜索所有“到[\ w] +”正则表达式,以获得大文本中的每个“到”匹配。然后对于每一场比赛,我会检查它是否存在于单词地图中。我想会更有效率。

答案 3 :(得分:0)

所述问题似乎非常适合非正则表达式解决方案。

或者,迭代r'\b%s(\B+)(?!-)(?!_)\b' % pre_pad的匹配项,并检查第一组匹配的单词是否在您的词典中。

答案 4 :(得分:0)

我不是蟒蛇专家,所以我的答案不具有权威性。但是,在我看来,正则表达式不是这种情况下的最佳工具。如果是字符串的结构

A was changed from B to C

是固定的,然后使用in运算符迭代你要检查的单词是不够的:

>>> "to blue" in "A was changed from red to blue"
True