Python正则表达式可选匹配组问题:加州刑法条文解析优化
加州刑法条文编号解析正则优化方案
需求说明
需要从加州法律条文编号(如PC 182(A)(1)、VC 22517、MC 8.80.060(F)等格式)中提取以下字段:
lawType:法律类型(两位大写字母,如PC/VC/MC)lawNumber:条文编号(允许数字、点号,结尾可带大写字母,如182、25400、369I、8.80.060)subsection:子章节(大写字母,如A/C/F)subsubsection:子子章节(数字,如1/6)
原实现用三个正则分别匹配不同格式的编号,现需合并为一个正则表达式完成所有匹配。
原正则问题分析
原尝试的正则(?P<lawType>[A-Z]{2})[ ](?P<lawNumber>[0-9.]*[A-Z]?)\((?P<subsection>[A-Z])\)?\((?P<subsubsection>[0-9])\)?无效,原因是仅将单个括号标记为可选,而非将(subsection)和(subsubsection)作为完整的可选组。当缺少子章节时,正则会尝试匹配单独的右括号,导致匹配失败。
优化后的正则表达式
(?P<lawType>[A-Z]{2}) (?P<lawNumber>[0-9.]*[A-Z]?)(?:\((?P<subsection>[A-Z])\))?(?:\((?P<subsubsection>[0-9])\))?
正则各部分解释
(?P<lawType>[A-Z]{2}):匹配两位大写字母的法律类型:匹配类型与编号之间的空格(?P<lawNumber>[0-9.]*[A-Z]?):匹配条文编号,支持数字、点号,结尾可选大写字母(?:\((?P<subsection>[A-Z])\))?:非捕获组包裹完整的子章节结构(X),?标记该组可选,匹配到的大写字母存入subsection字段(?:\((?P<subsubsection>[0-9])\))?:同理,非捕获组包裹子子章节结构(数字),匹配到的数字存入subsubsection字段
完整Python代码示例
import re lineValue = 'PC 182(A)(1); PC 25400(A)(1); PC 25850(C)(6); PC 32310; VC 12500(A); VC 22517; VC 23103(A)' # lineValue = 'PC 148(A)(1); PC 369I; PC 587C; MC 8.80.060(F)' chargeList = map(lambda x: x.strip(), lineValue.split(';')) pattern = re.compile(r'(?P<lawType>[A-Z]{2}) (?P<lawNumber>[0-9.]*[A-Z]?)(?:\((?P<subsection>[A-Z])\))?(?:\((?P<subsubsection>[0-9])\))?') for thisCharge in chargeList: m = pattern.match(thisCharge) if m: detail = m.groupdict() # 过滤未匹配到的空字段 filtered_detail = {k: v for k, v in detail.items() if v is not None} print(filtered_detail) else: print(f'NO MATCH: {thisCharge}')
输出示例
运行代码后,所有格式的条文编号都会被正确匹配,输出类似:
{'lawType': 'PC', 'lawNumber': '182', 'subsection': 'A', 'subsubsection': '1'} {'lawType': 'PC', 'lawNumber': '25400', 'subsection': 'A', 'subsubsection': '1'} {'lawType': 'PC', 'lawNumber': '25850', 'subsection': 'C', 'subsubsection': '6'} {'lawType': 'PC', 'lawNumber': '32310'} {'lawType': 'VC', 'lawNumber': '12500', 'subsection': 'A'} {'lawType': 'VC', 'lawNumber': '22517'} {'lawType': 'VC', 'lawNumber': '23103', 'subsection': 'A'}
内容的提问来源于stack exchange,提问作者Evan Jones
相关产品推荐
相关产品推荐

