Python正则匹配调用group()报NoneType属性错误原因排查
错误原因
这个报错的触发逻辑很明确:re.search() 按指定规则在目标字符串中匹配不到符合要求的内容时,返回值为None,None类型没有group方法,直接调用就会抛出你看到的属性错误。
你的代码做了两个脱离实际文件结构的刚性假设,只要有一个不成立,就会导致正则匹配失败:
- 假设所有以
.Text开头的行,它的下一行(索引为line+1的行)一定是双引号包裹的替换值。但实际Word VBA查找替换宏的代码结构根本不满足这个规律:.Text配置行后面经常跟着其他非字符串参数,比如.Wrap = wdFindContinue、.MatchCase = False、.MatchWholeWord = False这类不带双引号的配置项,这时候去下一行匹配双引号内容必然失败- 部分宏代码里查找项、替换项可能写在同一行,或者长字符串被拆分为多行,下一行根本不是完整的替换值
- 假设所有双引号内部至少有1个字符。你写的正则用了
.+?匹配引号内容(要求至少匹配1个字符),如果遇到空字符串赋值的场景,比如.Replacement.Text = "",正则同样会匹配失败返回None。
修正代码
不要用「识别到.Text行就固定取下一行」的硬编码位置逻辑,改成逐行遍历分别识别查找项、替换项,同时增加匹配结果判空,避免空值调用方法:
import re find_replace_dict = {} current_search_text = None # 调整正则为匹配0个及以上字符,兼容空字符串场景 quote_pattern = re.compile(r'"(.*?)"') with open('Macros.txt', 'r', encoding='utf-8') as f: for line in f: stripped_line = line.lstrip() # 识别查找文本 if stripped_line.startswith('.Text ='): match = quote_pattern.search(stripped_line) if match: current_search_text = match.group(1) # 识别对应替换文本,存入字典 elif stripped_line.startswith('.Replacement.Text =') and current_search_text is not None: match = quote_pattern.search(stripped_line) if match: find_replace_dict[current_search_text] = match.group(1) current_search_text = None print(find_replace_dict)
这个写法不依赖行与行的相邻位置关系,只要宏遵循标准VBA查找替换的写法(先定义查找文本、再定义替换文本),就能正确提取键值对,同时不会因为个别行结构不符合预期直接崩溃。
内容的提问来源于stack exchange,提问作者Python-lover
相关产品推荐
相关产品推荐

