如何处理正则匹配返回None触发的AttributeError并跳过异常记录
问题根因
re.search()匹配失败时会返回None,此时直接链式调用返回结果的start()、end()方法,必然触发AttributeError。
原代码存在两处明确的报错隐患:
extract_Access_Rule函数仅校验了DATA(是否存在,未校验右括号)的匹配结果,当文本不含右括号时,直接取re.search('[)]', text).end()会报错- 提取
Access_Rule_DataBase字段时,未校验UID(的匹配结果,目标文本不含该片段时同样会触发属性错误
修复方法
核心原则:所有正则匹配结果先存入变量,判断非空后再调用位置方法;匹配失败时返回空值(可根据业务需求调整为原文本、特殊标记值),不要直接链式调用匹配方法。若需要跳过匹配失败的记录,可在全量字段处理完成后,统一过滤空值行即可,不要在apply函数内直接跳行(pandas的apply逐元素执行,无内置跳过行的逻辑)。
修复后的可运行代码:
import re def extract_Access_Rule(text): # 提前存储匹配结果,既避免重复执行正则,也方便做非空判断 data_part_match = re.search(r'DATA\(', text) right_bracket_match = re.search(r'\)', text) # 无右括号时直接返回空值,可按业务需求调整返回内容 if not right_bracket_match: return "" bracket_end_pos = right_bracket_match.end() + 1 if data_part_match: return text[bracket_end_pos : data_part_match.start()] else: return text[bracket_end_pos:] # 提取Access_Rule_Value字段 access_HR_attestaion_application['Access_Rule_Value'] = access_HR_attestaion_application['Access_Rule'].apply(extract_Access_Rule) # 增加空值判断,避免空值调用replace报错 access_HR_attestaion_application['Access_Rule_Value'] = access_HR_attestaion_application['Access_Rule_Value'].apply( lambda x: x.replace(".", "") if isinstance(x, str) else "" ) # 提取Access_Rule_DataBase字段 database_regex = r'UID\(' def extract_db_prefix(text): db_match = re.search(database_regex, text) if not db_match: return "" return text[:db_match.start()] access_HR_attestaion_application['Access_Rule_DataBase'] = access_HR_attestaion_application['Access_Rule'].apply(extract_db_prefix) # 若需要过滤匹配失败的记录,取消注释下行代码即可 # access_HR_attestaion_application = access_HR_attestaion_application[ # (access_HR_attestaion_application['Access_Rule_Value'] != "") & # (access_HR_attestaion_application['Access_Rule_DataBase'] != "") # ]
优化说明
- 所有正则匹配逻辑只执行一次,将结果存入变量复用,减少不必要的性能消耗
- 所有调用
start()/end()的位置前都增加了非空判断,彻底解决属性报错问题 - 字符串替换环节增加类型校验,避免非字符串类型值调用
replace触发错误 - 正则特殊字符使用标准转义写法
\(、\),相比[(]、[)]可读性更高
内容的提问来源于stack exchange,提问作者Jonnyboi
相关产品推荐
相关产品推荐

