我见过有关Python的线程不接受超过100组的正则表达式。我有一个类似但(我认为?)不同的问题。
我有一个我为工作编写的python脚本,用于在大型(10-100MB)复杂日志文件中查找“有趣”的东西。我有一个字符串列表,其中每个字符串在调用re.search时用作正则表达式。每个正则表达式在每行日志记录中逐个运行。当我的列表有100个或更少的正则表达式字符串时,一切都运行peachy。但是当我在列表中再添加一个时,脚本运行得如此之慢以至于无用。
我写了一个模拟问题的简短脚本。有人可以帮我确定为什么会发生这种情况,并就我能做些什么提出一些建议吗?
以下是来自下面脚本的一些示例输出。我运行脚本的日志很少少于250,000行,通常是1-2百万行。
$ ./regexTest.py 100 10000
Running regex search
Done regex search
Time Elapsed: 0.734515 seconds
$ ./regexTest.py 101 10000
Running regex search
Done regex search
Time Elapsed: 44.428968 seconds
谢谢大家的时间!
#!/usr/bin/python
#------------------------------------------------------------------------------
# File: regexTest.py
# Description: Simulate the problem where trying to use a list of more than
# 100 regular expression strings slows the script to uselessness
# Example:
# ./regexTest.py 100 10000
# ./regexTest.py 101 10000
#------------------------------------------------------------------------------
from random import randint
import re
import sys
import time
def main():
if (len(sys.argv) != 3):
print "Usage: %s <NUM REGEXES> <LOG FILE LENGTH>" % sys.argv[0]
sys.exit(1)
numRegexes = int(sys.argv[1])
logFileLength = int(sys.argv[2])
regexes = []
# generate random regular expressions comprised of between 5 and 20
# lowercase letters
for i in range(numRegexes):
randomLetters = [chr(randint(97,120)) for x in range(randint(5,20))]
baseRegex = "".join(randomLetters)
regex = baseRegex + str(i)
regexes.append(regex)
# simulate the contents of a log file
data = []
for i in range(logFileLength):
randomLetters = [chr(randint(97,120)) for x in range(randint(20,100))]
logLine = "".join(randomLetters)
data.append(logLine)
print "Running regex search"
startTime = time.time()
for line in data:
for regex in regexes:
ret = re.search(regex, line)
if (ret is not None):
print "Regex found"
print "Done regex search"
endTime = time.time()
print "Time Elapsed: %f seconds" % (endTime - startTime)
if (__name__ == "__main__"):
main()
答案 0 :(得分:2)
你正在使用正则表达式错误;你应该编译它们。 re
模块中有一个缓存,用于不编译正则表达式的懒人; Python 2.7上的缓存大小为100,Python 3.4上为512。 re._MAXCACHE
可以使用缓存大小。在这100个条目用尽之后,所有编译模式将从缓存中排除。如果您发现自己的程序使用的re._MAXCACHE
以上版本正常,则应使用re.compile
对其进行预编译。
regexes = [ re.compile(i) for i in regexes ]
for line in data:
for regex in regexes:
ret = regex.search(line)
if ret is not None:
print("Regex found")
此外,如果您确实没有使用任何这些匹配项,则应将它们合并为一个。因此,您可以尝试将它们加入&#39; |&#39; bar运算符使它们彼此替代:
megaregex = re.compile('|'.join(regexes))
for line in data:
ret = megaregex.search(line)
if ret is not None:
print("Regex found")