使用re.search匹配多语言文件标记,递增字典值失败求排查
问题分析与修复方案
核心错误原因
re.search()返回值类型不匹配:re.search()成功匹配时返回的是Match对象,不是字符串,直接用==和字符串(比如'lang=\"de\"')比较永远不会成立,这就是字典数值始终不变的根本原因。- 正则表达式存在缺陷:原正则
r'\blang=\".*\"\B'里的.*是贪婪匹配,会从第一个双引号匹配到该行最后一个双引号,可能捕获多余内容;\B非单词边界的限制也可能导致匹配失效。
修复方案
推荐用正则分组直接捕获语言代码,避免冗余的字符串比较,代码更简洁高效:
import re import sys lang_freq = {'de':0, 'fr':0, 'it':0, 'rm': 0, 'en': 0, 'ch-de': 0} filename = sys.argv[1] # 用with语句自动管理文件资源,避免遗漏关闭 with open(filename, "r") as infile: for line in infile: # 正则分组捕获lang属性中的语言代码,支持带连字符的如ch-de match_result = re.search(r'lang="([a-z-]+)"', line) if match_result: lang_code = match_result.group(1) # 检查语言代码是否在目标字典中,避免KeyError if lang_code in lang_freq: lang_freq[lang_code] += 1 print(lang_freq)
关键调整说明
- 改用
with open(...)语法:自动处理文件打开/关闭流程,比手动调用close()更安全可靠。 - 优化正则表达式:
r'lang="([a-z-]+)"'通过括号精准捕获双引号内的语言代码,避免过度匹配。 - 先判断匹配结果是否存在:避免
None对象调用group()方法引发报错。 - 直接用语言代码更新字典:无需多次
if判断,逻辑更简洁。
关于==判断的疑问
不能直接用==比较re.search()返回的Match对象和字符串,两者类型完全不同。如果一定要保留原有的多if判断逻辑,需要先通过match_result.group()获取匹配到的完整字符串,再做比较(仅作示例,不推荐这种冗余写法):
match_result = re.search(r'lang=".*?"', line) # 用非贪婪匹配.*?避免过度捕获 if match_result: match_str = match_result.group() if match_str == 'lang="de"': lang_freq['de'] +=1 elif match_str == 'lang="fr"': lang_freq['fr'] +=1 # 其他语言判断...
内容的提问来源于stack exchange,提问作者mbcr
相关产品推荐
相关产品推荐

