我的第一个想法是让正则表达式引擎来处理这个问题。通常它们被优化用于处理大量文本,所以性能应该不会有太多的问题。这是一种暴力方法,但性能似乎还可以。你可以将输入分成若干段,然后让多个进程来处理它们。以下是我在 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个组的单个regexp。
(group1)|(group2)|(group3)|...
。我猜您将不得不对可以在正则表达式中具有含义的内容进行输入清理(例如
?
等)。那就是
monster_regexp
。
对此字符串进行测试,可以在一次操作中测试100个模式。有一些方法可以获取匹配的确切组。我测试了10000个字符串,其中80%应该匹配,10%不匹配。它会短路,所以如果成功,它将比较快。失败将不得不运行整个regexp,因此它将更慢。您可以根据输入的频率对事物进行排序,以获得更多的性能。
我在我的计算机上运行了这个程序,这是我的时间。
python /tmp/scratch.py 0.13s user 0.00s system 97% cpu 0.136 total
这还不错。
然而,对于如此大的正则表达式运行模式并失败将需要更长时间,因此我更改了输入,使用大量随机生成的不匹配字符串进行尝试。 10000个字符串都不匹配monster_regexp,我得到了这个结果。
python /tmp/scratch.py 3.76秒 用户0.01秒 系统99% CPU 3.779 总计
new Function
创建),如果这有助于获得更好的性能。 - Rakesh Pai