缺少在其他人中匹配命名组的名称

时间:2014-01-25 11:20:47

标签: python regex

这是一个在另一个内部使用命名组的代码。

import re

text = "def oneFunc(x, y): return 0"

pattern = re.compile(
    r"(?P<DEF_FUNC>def (?P<NAME_FUNC>\w+)\s*\((.*?)\):)|(?P<OTHERS>\w+)"
)

for m in pattern.finditer(text):
    name = next(k for k, v in m.groupdict().items() if v)
    print((m.group(), m.start(), name))

这是我的输出。

('def oneFunc(x, y):', 0, 'NAME_FUNC')
('return', 19, 'OTHERS')
('0', 26, 'OTHERS')

我遇到的问题是我的名字NAME_FUNC而不是DEF_FUNC。为什么?

我可以在匹配文本'def oneFunc(x, y):'中使用的组在我的示例中是('oneFunc', 'NAME_FUNC')吗?

更新“愚蠢”问题

该方法使用的以下代码并不好。

import re

text = "def oneFunc(x, y): return 0"

pattern = re.compile(
    r"(?P<DEF_FUNC>def (?P<NAME_FUNC>\w+)\s*\((.*?)\):)|(?P<OTHERS>\w+)"
)

print('---', text, sep = "\n")

for m in pattern.finditer(text):
    print('---', m.groupdict(), '', sep = "\n")

这表明我们拥有所有信息,因为我们有以下输出。

---
def oneFunc(x, y): return 0
---
{'NAME_FUNC': 'oneFunc', 'DEF_FUNC': 'def oneFunc(x, y):', 'OTHERS': None}

('def oneFunc(x, y):', 0, 'NAME_FUNC')
---
{'NAME_FUNC': None, 'DEF_FUNC': None, 'OTHERS': 'return'}

('return', 19, 'OTHERS')
---
{'NAME_FUNC': None, 'DEF_FUNC': None, 'OTHERS': '0'}

('0', 26, 'OTHERS')

1 个答案:

答案 0 :(得分:0)

因为词典中没有保证顺序。 (MatchObject.groupdict的返回值是字典)

例如,在以下示例中,OTHERS位于NAME_FUNC之前。

>>> d = {'DEF_FUNC': 'def oneFunc(x, y):',
         'NAME_FUNC': 'oneFunc',
         'OTHERS': None}
>>> d.items()
[('DEF_FUNC', 'def oneFunc(x, y):'), ('OTHERS', None), ('NAME_FUNC', 'oneFunc')]

以下表达式会在NAME_FUNC部分匹配时为您DEF_FUNC,否则为OTHERS

>>> d['NAME_FUNC'] if d['DEF_FUNC'] is not None else d['OTHERS']
'oneFunc'
>>> d['NAME_FUNC'] if d['DEF_FUNC'] else d['OTHERS']
'oneFunc'

>>> import re
>>>
>>> text = "def oneFunc(x, y): return 0"
>>>
>>> pattern = re.compile(
...     r"(?P<DEF_FUNC>def (?P<NAME_FUNC>\w+)\s*\((.*?)\):)|(?P<OTHERS>\w+)"
... )
>>>
>>> for m in pattern.finditer(text):
...     d = m.groupdict()
...     key = 'NAME_FUNC' if d['DEF_FUNC'] else 'OTHERS'
...     print('{}: {}'.format(key, d[key]))
...
NAME_FUNC: oneFunc
OTHERS: return
OTHERS: 0