Python移除文本行尾注释(排除引号内#)的正则方案求助
问题描述
我正在写Python代码,要解析以#开头注释的文本文件,需要移除行尾注释。一开始用str.rfind('#'),但碰到##开头的注释或者一行多个注释(比如#comment1 #comment2)就不行。后来试了re.sub的各种组合,但又遇到字符串里(比如"attempt #3")包含#的情况——这些文件里字符串用双引号包裹,字符字面量用单引号,和C语言类似。需要实现一种逻辑:移除行尾注释,但不处理单/双引号内的#。
示例输入
variable_name ## sometimes used ## variable:L"name####": variable_name = "Update Gen11 E5 ROM version to 1.34_04_25_2023 (#24201)" file_name #comment1 #comment2
期望输出
variable_name variable_name = "Update Gen11 E5 ROM version to 1.34_04_25_2023 (#24201)" file_name
规则说明:
- 若引号外有前置
#,则引号内的#也会被当作注释的一部分移除(比如第一个示例) - 若
#仅在引号内且引号外无前置#,则行内容保持不变(第二个示例) - 从第一个引号外的
#开始截断行内容(第三个示例)
解决方案
核心思路是先识别出字符串/字符字面量的范围,只在这些范围之外处理#注释。以下是具体实现:
实现代码
import re def remove_line_comments(line): # 正则匹配:捕获所有不在单/双引号内的前置内容,移除第一个非引号内#及之后的注释 pattern = r''' ( # 分组1:保留的内容(引号内或引号外到#之前的部分) (?: "([^"\\]|\\.)*" # 匹配双引号字符串,包含转义字符 | '([^'\\]|\\.)*' # 匹配单引号字符串,包含转义字符 | [^#"]+ # 匹配非#非引号的普通内容 )* ) \#.* # 匹配第一个不在引号内的#及其后续所有内容 ''' # 用分组1的内容替换原匹配,实现注释截断 result = re.sub(pattern, r'\1', line, flags=re.VERBOSE) # 去除行尾多余空格,和示例输出对齐 return result.rstrip() # 测试示例输入 test_lines = [ 'variable_name ## sometimes used ## variable:L"name####":', 'variable_name = "Update Gen11 E5 ROM version to 1.34_04_25_2023 (#24201)"', 'file_name #comment1 #comment2' ] for line in test_lines: print(remove_line_comments(line))
代码说明
- 正则采用verbose模式拆分逻辑,可读性更强:
- 分别匹配双引号、单引号包裹的字符串,包含转义字符(比如
\"),确保引号内的#不被误识别 - 匹配非
#非引号的普通内容,覆盖注释前的代码部分 - 最后匹配第一个不在引号内的
#及其后所有内容,作为要移除的注释
- 分别匹配双引号、单引号包裹的字符串,包含转义字符(比如
re.sub通过保留分组1的内容,直接截断注释部分rstrip()清理行尾多余空格,和期望输出格式一致
测试结果
运行代码后输出:
variable_name variable_name = "Update Gen11 E5 ROM version to 1.34_04_25_2023 (#24201)" file_name
完全符合预期效果。
内容的提问来源于stack exchange,提问作者Cyberclops
相关产品推荐
相关产品推荐

