Python re.findall regex挂起或非常慢

Python re.findall regex挂起或非常慢,python,regex,Python,Regex,我的输入文件是一个大的txt文件,其中包含从一个打开的文本库中获取的连接文本。我现在试图只提取书本身的内容,并过滤掉其他内容,如免责声明等。因此,我的大文本文件中有大约100个文档(大约50MB) 然后,我确定了内容本身的开始和结束标记,并决定使用Python正则表达式来查找开始和结束标记之间的所有内容。总之,正则表达式应该查找开始标记,然后匹配它之后的所有内容,并在到达结束标记后停止查找,然后重复这些步骤,直到到达文件的结尾 当我将一个100kb大小的小文件输入到其中时,以下代码可以完美地工作

我的输入文件是一个大的txt文件,其中包含从一个打开的文本库中获取的连接文本。我现在试图只提取书本身的内容,并过滤掉其他内容,如免责声明等。因此,我的大文本文件中有大约100个文档(大约50MB)

然后,我确定了内容本身的开始和结束标记,并决定使用Python正则表达式来查找开始和结束标记之间的所有内容。总之,正则表达式应该查找开始标记,然后匹配它之后的所有内容,并在到达结束标记后停止查找,然后重复这些步骤,直到到达文件的结尾

当我将一个100kb大小的小文件输入到其中时,以下代码可以完美地工作:

import codecs
import re

outfile = codecs.open("outfile.txt", "w", "utf-8-sig")
inputfile = codecs.open("infile.txt", "r", "utf-8-sig")
filecontents = inputfile.read()
for result in re.findall(r'START\sOF\sTHE\sPROJECT\sGUTENBERG\sEBOOK.*?\n(.*?)END\sOF\THE\sPROJECT\sGUTENBERG\sEBOOK', filecontents, re.DOTALL):
    outfile.write(result)
outfile.close()
但是,当我在较大的文件上使用这个regex操作时,它不会做任何事情,程序只是挂起。我在一夜之间测试了它,看看它是否很慢,甚至在大约8个小时后,程序仍然被卡住

我很肯定问题的根源是 (.*?) 正则表达式的一部分,与re.DOTALL结合使用。 当我在较小距离上使用类似的正则表达式时,脚本将运行良好且快速。 我现在的问题是:为什么这只是冻结一切?我知道分隔符之间的文本并不小,但是50mb的文件应该不会太难处理,对吗? 我是否错过了一个更有效的解决方案


提前感谢。

您认为使用多次出现的序列
*
会导致问题是正确的。问题是,解算器正在尝试许多可能的
*
组合,结果称为

通常的解决方案是将
替换为更具体的字符类,通常是您试图终止第一个
*
的产品。比如:

`[^\n]*(.*)`

因此,捕获组只能从第一个换行符匹配到最后一个换行符。另一种选择是认识到正则表达式解决方案可能不是最好的方法,使用上下文无关的表达式(例如),或者首先将输入分解为更小、更易于消化的块(例如,使用
corpus.split('\n')

此问题的另一个解决方法是对匹配字符的数量增加一个合理的限制

因此,不要像这样:

[abc]*.*[def]*
可以将其限制为每个字符组1-100个实例

[abc]{1,100}.{1,100}[def]{1,100}

这并不适用于所有情况,但在某些情况下,这是一个可接受的快速修复方法。

如果您同时读取整个文件,并调用findall正则表达式,那么肯定缺少一个更有效的解决方案,是的,
(.*)
re.DOTALL
结合使用会导致大量回溯。不使用正则表达式捕获内容会更容易;逐行阅读内容,检查各行中的开始或结束标记,并在收到每一行时写入(而不是建立一个大的内存缓冲区),这似乎是一个成功的方法,当然是为了提高效率。同样感谢您,逐行解决方案工作得非常好。感谢您的澄清,非常感谢。一行一行的进行对我来说非常有效。回答很好。非常感谢。