我的第一个想法是让正则表达式引擎不厌其烦地处理这个问题。它们通常经过优化以处理大量文本,因此不应该带来太多性能问题。这是蛮力,但性能似乎还可以。您可以将输入分成几部分并让多个进程处理它们。这是我经过适度测试的解决方案(在 Python 中)。
import random
import string
import re
def create_random_sentence():
nwords = random.randint(4, 10)
sentence = []
for i in range(nwords):
sentence.append("".join(random.choice(string.lowercase) for x in range(random.randint(3,10))))
ret = " ".join(sentence)
print ret
return ret
patterns = [ r"Hi there, [a-zA-Z]+.",
r"What a lovely day today!",
r"Lovely sunset today, [a-zA-Z]+, isn't it?",
r"Will you be meeting [a-zA-Z]+ today, [a-zA-Z]+\?"]
for i in range(95):
patterns.append(create_random_sentence())
monster_pattern = "|".join("(%s)"%x for x in patterns)
print monster_pattern
print "--------------"
monster_regexp = re.compile(monster_pattern)
inputs = ["Hi there, John.",
"What a lovely day today!",
"Lovely sunset today, John, isn't it?",
"Will you be meeting Linda today, John?",
"Goobledigoock"]*2000
for i in inputs:
ret = monster_regexp.search(i)
if ret:
print ".",
else:
print "x",
我已经创建了一百种模式。这是 python regexp 库的最大限制。其中 4 个是您的实际示例,其余的都是随机句子,只是为了稍微强调一下表现。
然后我将它们组合成一个包含 100 个组的正则表达式。(group1)|(group2)|(group3)|...
. 我猜你将不得不为在正则表达式中有意义的东西(比如?
等)清理输入。就是这样monster_regexp
。
针对这个测试一个字符串在一次测试中针对 100 个模式进行测试。有一些方法可以提取出匹配的确切组。我测试了 10000 个字符串,其中 80% 应该匹配,10% 不匹配。它很短,所以如果成功的话,它会比较快。失败必须贯穿整个正则表达式,所以它会变慢。您可以根据输入频率对事物进行排序,以从中获得更多性能。
我在我的机器上运行了这个,这是我的时机。
python /tmp/scratch.py 0.13s user 0.00s system 97% cpu 0.136 total
这还不错。
但是,针对如此大的正则表达式运行模式并失败将花费更长的时间,因此我将输入更改为具有许多不匹配的随机生成的字符串,然后尝试。10000 个字符串都不匹配 monster_regexp,我得到了这个。
python /tmp/scratch.py 3.76s user 0.01s system 99% cpu 3.779 total