Python正则匹配问题:捕获分隔符间非注释多行文本失败
问题描述
需要从带分隔符的文件中,捕获start_of_compile与end_of_compile之间的所有非注释多行内容。尝试用(.*)匹配多行失败,运行代码时触发AttributeError: 'NoneType' object has no attribute 'group'错误。
文件内容示例
#####start_of_compile - DO NOT MODIFY THIS LINE############# ################################################################## parse these lines in between them ... .... ################################################################### #####end_of_compile -DO NOT MODIFY THIS LINE################# ###################################################################
代码示例
def checkcompileqel(): compiledelimiters = ['start_of_compile_setup'] with open("compile.qel", "r") as compile_fh: lines = compile_fh.read() matchstart = re.compile(r'^#+ #+start.*#+ #+(.*)#+ #+end.*#+ #+',re.MULTILINE) print(matchstart.match(lines).group(1))
错误信息
Traceback (most recent call last): File "/process_tools/testcode.py", line 25, in <module> print(checkcompileqel()) File "/home/process_tools/testcode.py", line 10, in checkcompileqel print(matchstart.match(lines).group(0)) AttributeError: 'NoneType' object has no attribute 'group'
解决方案
问题根源
.*不匹配换行符:默认正则的.不会匹配换行,re.MULTILINE仅影响^和$的匹配位置,不改变.的行为,导致跨多行的内容无法被捕获。- 正则结构与文件格式不匹配:原正则的换行写法(直接在字符串内换行)不符合Python语法,且标记行的匹配逻辑和实际文件结构不符,导致正则完全找不到匹配项,返回
None,调用group()时触发错误。 match()方法限制:match()仅从字符串开头匹配,若文件开头存在其他内容(哪怕示例中没有,实际场景可能出现)就会匹配失败,应改用search()查找任意位置的匹配。
修正后的代码
import re def checkcompileqel(): with open("compile.qel", "r") as compile_fh: content = compile_fh.read() # 匹配start和end标记之间的内容,开启DOTALL让.匹配换行,MULTILINE让^$匹配每行首尾 pattern = re.compile( r'^#+start_of_compile.*?$\n(.*?)^#+end_of_compile.*?$', re.DOTALL | re.MULTILINE ) match_result = pattern.search(content) if match_result: # 提取中间内容后,过滤掉全是#的注释行 raw_content = match_result.group(1) non_comment_lines = [] for line in raw_content.split('\n'): stripped_line = line.strip() # 跳过全注释行和空行(空行可根据需求保留) if not stripped_line or stripped_line.startswith('#') and all(c == '#' for c in stripped_line): continue non_comment_lines.append(stripped_line) print('\n'.join(non_comment_lines)) else: print("未找到匹配的内容") checkcompileqel()
代码说明
- 正则调整:启用
re.DOTALL让.匹配换行符,re.MULTILINE让^和$匹配每行首尾,确保精准定位start和end标记行。 - 非注释内容过滤:提取中间内容后,通过判断行是否为全注释行来过滤无效内容,保留需要的文本。
- 空值判断:先检查
match_result是否为None,避免触发AttributeError。
内容的提问来源于stack exchange,提问作者Prashanth Iyer
相关产品推荐
相关产品推荐

