Python RE,可选匹配组问题

rm5edbpk  于 2022-12-02  发布在  Python
关注(0)|答案(1)|浏览(119)

如果有人问过这个问题,我很抱歉。我正在解析加州州刑法典中的一些法律编号,这样它们就可以在现有的数据库中运行,以返回法律的简明语言标题。例如:
PC 182(A)(1); PC 25400(A)(1); PC 25850(C)(6); PC 32310; VC 12500(A);维生素C 22517;维生素C 23103(A)
每一个都将被拆分为“;'并解析为:
{“法律类型”:“计算机”,“法律编号”:“182”、“小节”:“A”、"子节“:'1'}退货:串谋犯罪
以下是我的RE搜索:

(?P<lawType>[A-Z]{2})[ ](?P<lawNumber>[0-9.]*[A-Z]?)\((?P<subsection>[A-Z])\)?\((?P<subsubsection>[0-9])\)?

每一条法则至少应该有类型和编号(例如PC 182),但有时它们也有子部分和子子部分(例如(A)(1))。这两个子部分需要是可选的,但上面的搜索没有使用'?'来获取它们。这段代码可以工作,但我想通过一次搜索使其更紧凑:

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(';'))
for thisCharge in chargeList:
    m = re.match(r'(?P<lawType>[A-Z]{2})[ ](?P<lawNumber>[0-9.]*[A-Z]?)\((?P<subsection>[A-Z])\)\((?P<subsubsection>[0-9])\)', thisCharge)
    if m:
        detail = m.groupdict()
        print(detail)

    else:
        m = re.match(r'(?P<lawType>[A-Z]{2})[ ](?P<lawNumber>[0-9.]*[A-Z]?)\((?P<subsection>[A-Z])\)', thisCharge)
        if m:
            detail = m.groupdict()
            print(detail)

        else:
            m = re.match(r'(?P<lawType>[A-Z]{2})[ ](?P<lawNumber>[0-9.]*[A-Z]?)', thisCharge)
            if m:
                detail = m.groupdict()
                print(detail)

            else:
                print('NO MATCH: ' + str(thisCharge))

我有三个不同的搜索,如果“?”可选组标记按预期工作,这应该是不必要的。有人能提供一个想法吗?

luaexgnf

luaexgnf1#

问题在于如何应用?使每个子部分都是可选的。?只应用于它前面的术语。在您的示例中,这只是每个子部分的右括号。因此,您需要无条件地为每个子部分术语使用左括号和数字或字母。要解决此问题,只需将完整的子部分项用一组额外的括号括起来,并将?应用于这些组。

import re

data = "PC 182(A)(1); PC 25400(A)(1); PC 25850(C)(6); PC 32310; VC 12500(A); VC 22517; VC 23103(A)"

exp = re.compile(r"(?P<lawType>[A-Z]{2})[ ](?P<lawNumber>[0-9.]*[A-Z]?)(?:\((?P<subsection>[A-Z])\))?(?:\((?P<subsubsection>[0-9])\))?")

def main():
    r = exp.findall(data)
    print(r)

main()

产生:

[('PC', '182', 'A', '1'), ('PC', '25400', 'A', '1'), ('PC', '25850', 'C', '6'), ('PC', '32310', '', ''), ('VC', '12500', 'A', ''), ('VC', '22517', '', ''), ('VC', '23103', 'A', '')]

以下示例说明如何使用表达式,通过组标签分别为每个法则曲线挑选信息:

def main():
    p = 0
    while True:
        m = exp.search(data[p:])
        if not m:
            break
        print('Type:', m.group('lawType'))
        print('Number:', m.group('lawNumber'))
        if m.group('subsection'):
            print('Subsection:', m.group('subsection'))
        if m.group('subsubsection'):
            print('Subsubsection:', m.group('subsubsection'))
        print()
        p += m.end()

测试结果

Type: PC
Number: 182
Subsection: A
Subsubsection: 1

Type: PC
Number: 25400
Subsection: A
Subsubsection: 1

Type: PC
Number: 25850
Subsection: C
Subsubsection: 6

Type: PC
Number: 32310

Type: VC
Number: 12500
Subsection: A

Type: VC
Number: 22517

Type: VC
Number: 23103
Subsection: A

注意到您在应用正则表达式之前是如何预拆分数据的,我想您可能想看看我将如何仅使用正则表达式匹配来处理每个术语。

相关问题