我有一个正则表达式匹配器,用于检查Python中的Web流量。问题是,有时,如果页面大于1MB并且由单个字符串组成,则正则表达式将永远完成。我想知道是否有办法设置最大执行超时?
我的脚本从文件中读取正则表达式,然后一次处理一个:
def match_keywords_add_to_es(pastes):
match_list = get_re_match_list()
for paste in pastes:
log.info("matching %s"%paste["key"])
for match in match_list:
matched = match[1].findall(paste["raw"].lower())
if len(matched) > 0:
try:
paste["keywords"] = match[0]
res_paste = Paste(dictionary=paste)
Paste.add_paste(res_paste)
except Exception,e:
log.error("Failed to add the paste "+str(paste)+" with error %s"%e)
示例正则表达式:
secret_key:
match: .*secret(_)?key\s*=\s*(.*)?[A-Za-z0-9\/]{40}(.*)?.*
access_key:
match: .*access(_)?key\*=\*(.*)?[A-Z0-9]{20}(.*)?.*
example.com:
match: .*example\.com.*
答案 0 :(得分:3)
我将专注于你的一个regexen的这一部分:
\s*(.*)?[A-Za-z0-9\/]{40}(.*)?.*
首先,\s*(.*)?
。这样做的问题是\s*
可以反刍空白,然后由(.*)?
消耗(问号也是不必要的)。结果是,如果你的正则表达式得到这么多,你会得到很多完全无用的回溯,但是在其余的那一行上却无法匹配。您可能希望使用比.
更严格的内容,强制\s
尽可能多地匹配空格,并拒绝再次放弃它们:
\s*(\S.*|)
这匹配一个非空白字符后跟任何内容或空字符串。它不能消耗由\s
反刍的空白,因此你的回溯会减少痛苦。
向前跳过,这种结构完全莫名其妙:(.*)?.*
。第一个点星将消耗该行上的所有剩余字符,因此您不需要第二个。 Star也可以匹配零次,因此在这种情况下你也不需要问号。
您也无需逃避/
,正如WiktorStribiżew在评论中指出的那样。
因此修改后的片段如下所示:
\s*(\S.*|)[A-Za-z0-9/]{40}(.*)
作为最后一点,我建议让(.*)
个序列中的一个(并且只有一个)变得懒惰,因为我发现很难判断你是否会抓住第一个部分匹配[A-Za-z0-9\/]{40}
的行或匹配的行的最后部分。我相信让第二个懒惰不会改变正则表达式的含义,但我不是100%肯定这一点,所以一定要测试它。