计算Python正则表达式中捕获的命名组的数量和命名组的总数

时间:2013-02-28 00:00:22

标签: python regex

我有两个清单。一个列表ref包含允许越来越灵活的正则表达式项,另一个列表input包含要与正则表达式匹配的输入列表。 到目前为止,我能够在下面创建match字典。下面是我正在尝试创建的字典match_updmatch由输入中的键组成,其中包含来自ref的相应匹配值。值项由ref中每个匹配的元组项的第二项组成。此外,match中的每个值都包含实现匹配的命名捕获组。所需的输出match_upd将包含相同的值,但这些值中的每一个还将包括匹配的捕获组中成功匹配的命名捕获组的数量,以及在匹配的捕获组内匹配的那些。 下面的例子非常抽象,如果这让它变得混乱,我道歉。基本上我正在尝试计算匹配中可选捕获组的数量,并且还计算参与匹配的这些组的数量。我正在使用Python的新regex模块。

input = [(' PREDIR NAME SUFTYP B1 ', 'CCCC, 11111'), (' NAME SUFTYP SUFDIR A1 ', 'CCCC, 11111')]

ref = [('(?P<iter1> PREDIR PRETYP NAME SUFTYP SUFDIR )|(?P<iter2> (?P<iter2pd>PREDIR )?(?P<iter2pt>PRETYP )?NAME(?P<iter2st> SUFTYP)?(?P<iter2sd> SUFDIR)? .*? )|(?P<iter3>.*? NAME .*? )', ['PREDIR,PRETYP,NAME,SUFTYP,SUFDIR,', 'CCCC, 11111']), ('(?P<iter1> NAME )|(?P<iter2> NAME )|(?P<iter3>.*? NAME .*? )', [',,NAME,,,', 'CCCC, 11111']), ('(?P<iter1> PREDIR NAME SUFTYP )|(?P<iter2> (?P<iter2pd>PREDIR )?NAME(?P<iter2st> SUFTYP)? .*? |(?P<iter3> .*? NAME .*?)', ['PREDIR,,NAME,SUFTYP,,', 'CCCC, 11111'])]

match {' NAME SUFTYP SUFDIR A1 , CCCC, 11111': (([',,NAME,,,', 'CCCC, 11111'], 'iter3'), (['PREDIR,,NAME,SUFTYP,,', 'CCCC, 11111'], 'iter2'), (['PREDIR,PRETYP,NAME,SUFTYP,SUFDIR,', 'CCCC, 11111'], 'iter2')), ' PREDIR NAME SUFTYP B1 , CCCC, 11111': ((['PREDIR,,NAME,SUFTYP,,', 'CCCC, 11111'], 'iter2'),['PREDIR,PRETYP,NAME,SUFTYP,SUFDIR,', 'CCCC, 11111'], 'iter2'), ([',,NAME,,,', 'CCCC, 11111'], 'iter3'))}

match_upd {' NAME SUFTYP SUFDIR A1 , CCCC, 11111': (([',,NAME,,,', 'CCCC, 11111'], 'iter3',0,0), (['PREDIR,,NAME,SUFTYP,,', 'CCCC, 11111'], 'iter2',1,2), (['PREDIR,PRETYP,NAME,SUFTYP,SUFDIR,', 'CCCC, 11111'], 'iter2',2,4)), ' PREDIR NAME SUFTYP B1 , CCCC, 11111': ((['PREDIR,,NAME,SUFTYP,,', 'CCCC, 11111'], 'iter2',2,2),['PREDIR,PRETYP,NAME,SUFTYP,SUFDIR,', 'CCCC, 11111'], 'iter2',2,4), ([',,NAME,,,', 'CCCC, 11111'], 'iter3',0,0))}

我可以使用以下代码生成match

def match(i,o,addr,ref,group):
    m = regex.fullmatch(i[0],o[0])
    if m:
        addr.append(str(o).strip('('')').replace("'",""))
        ref.append(i[1])
        m = m.groupdict()
        for k,v in m.items():
            if v is not None:
                group.append(k)

addr = []
ref = []
group = []

for i in ref:
    for t in input:
        if t[1] == i[1][2]:
            match(i,t,addr,ref,group)

unmatched = []
for i in input:
    unmatched.append(str(i).strip('('')').replace("'",""))

match_iter123 = zip(addr,zip(ref,group))
unmatched123 = list((set(unmatched)) - (set(addr)))

matchdict123 = {}
[matchdict123.setdefault(k,[]).append(v) for k,v in match_iter123]

matchdict = defaultdict(tuple)

for i in match_iter123:
    matchdict[i[0]] += i[1:]

match = {k:v for k, v in matchdict.items()}

我尝试为match_upd添加所需的输出效果不佳:

def match(i,o,addr,ref,group,matchattributes,totalattributes):
    m = regex.fullmatch(i[0],o[0])
    if m:
        addr.append(str(o).strip('('')').replace("'",""))
        ref.append(i[1])
        m = m.groupdict()
        for k,v in m.items():
            if v is not None and re.search(r'pd|pt|sd|st',k) is None:
                group.append(k)
        for k,v in m.items():
            if v is not None and re.search(r'pd|pt|sd|st',k) is not None:
                matchattributes.append(len(k))
        for k,v in m.items():
            if re.search(r'pd|pt|sd|st',k) is not None:
                totalattributes.append(len(k))

我是编程新手,如果这个答案很简单,请原谅我。我基本上需要计算最后两个for语句。感谢您的帮助和耐心。

1 个答案:

答案 0 :(得分:0)

我明白了。回想起来,这是一个非常简单的解决方案。我只需要确定matchattributestotalattributes变量的总计数。 +=函数是解决方案,将总数附加到空列表中。

def match(i,o,addr,ref,group,matchattributes,totalattributes):
    matchcounter = 0
    totalcounter = 0
    m = regex.fullmatch(i[0],o[0])
    if m:
        addr.append(str(o).strip('('')').replace("'",""))
        ref.append(i[1])
    m = m.groupdict()
    for k,v in m.items():
            if v is not None and re.search(r'pd|pt|sd|st',k) is None:
                group.append(k)
    for k,v in m.items():
        if v is not None and re.search(r'3(pd|pt|sd|st)',k):
            matchcounter += 1
    matchattributes.append(matchcounter)
    for k,v in m.items():
        if re.search(r'3(pd|pt|sd|st)',k):
            totalcounter += 1
    totalattributes.append(totalcounter)