如何使用REGEX提取字符串中从Run:到ENDMDL的文本内容?
正则提取跨多行内容的问题解决
你的pattern_tot匹配失败的核心原因是:Python正则默认情况下,.元字符不匹配换行符,而你要提取的内容跨了多行,所以中间的(.+)无法匹配换行部分,导致整个正则匹配失败。
解决方法
只需要开启正则的DOTALL模式(让.匹配包括换行在内的所有字符),同时优化正则表达式的写法,就能正确提取目标内容:
方法1:使用内嵌模式标志(?s)
import re with open("docking.txt","r") as f: new_content = f.read() # 内嵌(?s)开启DOTALL模式,非贪婪匹配中间内容,确保匹配到最近的ENDMDL # 如果要包含Run:和ENDMDL本身,用下面的正则: # pattern_tot = r'(?s)(Run:\s+\d+\s/\s\d+.+?DOCKED:\sENDMDL)' pattern_tot = r'(?s)Run:\s+\d+\s/\s\d+(.+?)DOCKED:\sENDMDL' for match in re.finditer(pattern_tot, new_content): # 提取中间的内容(不含Run:和ENDMDL) print(match.group(1).strip()) # 如果提取全部内容(含Run:和ENDMDL),则用match.group(0)或调整正则后的group(1)
方法2:调用正则方法时传入flags=re.DOTALL
import re with open("docking.txt","r") as f: new_content = f.read() pattern_tot = r'Run:\s+\d+\s/\s\d+(.+?)DOCKED:\sENDMDL' # 通过flags参数开启DOTALL模式 for match in re.finditer(pattern_tot, new_content, flags=re.DOTALL): # 输出从Run:到ENDMDL的完整内容 print(match.group(0))
关键细节说明
(?s)和re.DOTALL的作用完全一致,都是让.匹配所有字符(包括换行符)。- 使用
(.+?)非贪婪匹配模式,避免当文件中有多个ENDMDL时,匹配到最后一个而不是最近的那个,保证提取的是相邻的目标段落。
内容的提问来源于stack exchange,提问作者Riccardo Fusco
相关产品推荐
相关产品推荐

