Python正则大量使用.*触发灾难性回溯导致循环卡死如何解决
问题原因
- 你定义的
Starts_2dugaar_heseg正则集合所有模式都大量使用贪婪匹配的.*,且多个.*连续排列在长模式中。当待匹配文本不满足模式结尾的关键词要求时,正则引擎会反复回溯尝试所有可能的字符拆分路径,直接触发灾难性回溯,加上你循环遍历29个正则挨个匹配,最终导致程序卡死。
解决方案
方案1:修改正则量词(最小改动适配业务要求)
将所有模式中的贪婪.*替换为独占量词.*+,独占量词匹配到内容后不会回退回溯,匹配逻辑和原有.*完全一致,同时从根源避免灾难性回溯。再将所有模式合并为一个正则,避免循环29次匹配的额外开销:
import re Starts_2dugaar_heseg = ( r'.*Нэхэмжлэгч.*шүүх.*хуралдаанд.*гаргасан.*тайлбартаа:.*', r'.*Нэхэмжлэгч.*болон.*нэхэмжлэгчийн.*итгэмжлэгдсэн.*төлөөлөгч.*шүүхэд.*гаргасан.*нэхэмжлэл.*болон.*шүүх.*хуралдаанд.*гаргасан.*тайлбартаа:.*', r'.*Нэхэмжлэгч.*болон.*нэхэмжлэгчийн.*итгэмжлэгдсэн.*төлөөлөгч,.*өмгөөлөгч.*нар.*шүүхэд.*гаргасан.*нэхэмжлэл.*болон.*шүүх.*хуралдаанд.*гаргасан.*нэхэмжлэлдээ:.*', r'.*Нэхэмжлэгч.*болон.*нэхэмжлэгчийн.*өмгөөлөгч.*шүүхэд.*гаргасан.*нэхэмжлэл.*болон.*шүүх.*хуралдаанд.*гаргасан.*тайлбартаа:.*', r'.*Нэхэмжлэгч.*болон.*төлөөлөгч.*шүүхэд.*гаргасан.*нэхэмжлэл.*болон.*шүүх.*хуралдаанд.*гаргасан.*тайлбартаа:.*', r'.*Нэхэмжлэгч.*болон.*түүний.*итгэмжлэгдсэн.*төлөөлөгч.*шүүхэд.*гаргасан.*нэхэмжлэл,.*шүүх.*хуралдаанд.*гаргасан.*тайлбартаа:.*', r'.*Нэхэмжлэгч.*болон.*түүний.*итгэмжлэгдсэн.*төлөөлөгч.*шүүхэд.*гаргасан.*нэхэмжлэлдээ:.*', r'.*Нэхэмжлэгч.*гаргасан.*нэхэмжлэл.*болон.*шүүх.*хуралдаанд.*гаргасан.*тайлбартаа:.*', r'.*Нэхэмжлэгч.*итгэмжлэгдсэн.*төлөөлөгч.*шүүх.*хуралдаанд.*гаргасан.*тайлбартаа:.*', r'.*Нэхэмжлэгч.*итгэмжлэгдсэн.*төлөөлөгч.*шүүх.*хуралдаанд.*тайлбарлахдаа:.*', r'.*Нэхэмжлэгч.*итгэмжлэгдсэн.*төлөөлөгч.*шүүхэд.*гаргасан.*нэхэжмлэлийн.*шаардлагадаа:.*', r'.*Нэхэмжлэгч.*итгэмжлэгдсэн.*төлөөлөгч.*шүүхэд.*гаргасан.*нэхэмжлэл.*болон.*нэхэмжлэгч.*шүүх.*хуралдаанд.*гаргасан.*тайлбартаа:.*', r'.*Нэхэмжлэгч.*итгэмжлэгдсэн.*төлөөлөгч.*шүүхэд.*гаргасан.*нэхэмжлэл.*болон.*шүүх.*хуралдаанд.*гаргасан.*тайлбар:.*', r'.*Нэхэмжлэгч.*итгэмжлэгдсэн.*төлөөлөгч.*шүүхэд.*гаргасан.*нэхэмжлэл.*болон.*шүүх.*хуралдаанд.*гаргасан.*тайлбартаа:.*', r'.*Нэхэмжлэгч.*итгэмжлэгдсэн.*төлөөлөгч.*шүүхэд.*гаргасан.*нэхэмжлэлд.*болон.*шүүх.*хуралдаанд.*гаргасан.*тайлбарт:.*', r'.*Нэхэмжлэгч.*итгэмжлэгдсэн.*төлөөлөгч.*шүүхэд.*гаргасан.*нэхэмжлэлдээ:.*', r'.*Нэхэмжлэгч.*итгэмжлэгдсэн.*төлөөлөгч.*шүүхэд.*гаргасан.*нэхэмжлэлийн.*шаардлага.*болон.*шүүх.*хуралдаанд.*гаргасан.*тайлбартаа:.*', r'.*Нэхэмжлэгч.*итгэмжлэгдсэн.*төлөөлөгч.*шүүхэд.*гаргасан.*нэхэмжлэлээ.*дэмжиж.*шүүх.*хуралдаанд.*тайлбарлахдаа:.*', r'.*Нэхэмжлэгч.*нь.*нэхэмжлэлийн.*өөрчилсөн.*шаардлагадаа:.*', r'.*Нэхэмжлэгч.*нэхэмжлэгч.*нар.*шүүхэд.*гаргасан.*нэхэмжлэлдээ:.*', r'.*Нэхэмжлэгч.*нэхэмжлэл.*болон.*шүүх.*хуралдаан.*дээр.*гаргасан.*тайлбартаа:.*', r'.*Нэхэмжлэгч.*нэхэмжлэл.*болон.*шүүх.*хуралдаанд.*гаргасан.*тайлбартаа:.*', r'.*Нэхэмжлэгч.*нэхэмжлэлийн.*шаардлагаа.*дэмжиж.*шүүх.*хуралдаанд.*гаргасан.*тайлбартаа:.*', r'.*Нэхэмжлэгч.*нэхэмжлэлийн.*шаардлагаа.*өөрчилж.*гаргахдаа:.*', r'.*Нэхэмжлэгч.*нэхэмжлэлийн.*шаардлагаа.*өөрчлөн.*шүүхэд.*гаргасан.*тайлбартаа:.*', r'.*Нэхэмжлэгч.*нэхэмжлэлийн.*шаардлагыг.*тодруулахдаа.*болон.*шүүх.*хуралдаанд.*тайлбарлахдаа:.*', r'.*Нэхэмжлэгч.*өмгөөлөгч.*шүүх.*хуралдаанд.*гаргасан.*тайлбартаа:.*', r'.*Нэхэмжлэгч.*тал.*шүүх.*хуралдаанд.*гаргасан.*нэхэмжлэлийн.*тайлбартаа.*', r'.*шүүхэд.*нэхэмжлэлийн.*шаардлагаа.*нэмэгдүүлэх.*болон.*өөрчлөн.*гаргахдаа:.*' ) # 合并模式+替换为独占量词,Python 3.10以下版本可将.*+替换为惰性匹配.*?,也能大幅降低回溯概率 merged_pattern = re.compile('|'.join(pat.replace('.*', '.*+') for pat in Starts_2dugaar_heseg)) # 单次匹配即可,无需循环 start_chars = line[:250] if merged_pattern.search(start_chars): start = True print('start = True')
方案2:非正则实现(性能更高)
如果后续需要进一步提升性能,可以将每个模式的关键词按顺序提取,编写简单的顺序匹配函数判断关键词是否按顺序出现在文本中,完全规避正则回溯问题。
内容的提问来源于stack exchange,提问作者user15313738
相关产品推荐
相关产品推荐

