如何在Python中获取匹配正则表达式的组名?

Cha*_*eon 11 python regex python-2.7

问题是非常基本的,我不知道如何从匹配中找出组名.让我在代码中解释一下:

import re    
a = list(re.finditer('(?P<name>[^\W\d_]+)|(?P<number>\d+)', 'Ala ma kota'))
Run Code Online (Sandbox Code Playgroud)

如何获得a[0].group(0)匹配的组名称- 假设命名模式的数量可以更大?

简化示例以学习基础知识.

我可以反转匹配,a[0].groupdict()但它会很慢.

Mar*_*ers 29

您可以从编译的表达式中获取此信息:

>>> pattern = re.compile(r'(?P<name>\w+)|(?P<number>\d+)')
>>> pattern.groupindex
{'name': 1, 'number': 2}
Run Code Online (Sandbox Code Playgroud)

这使用RegexObject.groupindex属性:

一个字典,用于映射由(?P<id>)组编号定义的任何符号组名称.如果模式中没有使用符号组,则字典为空.

如果您只能访问匹配对象,则可以使用以下MatchObject.re属性访问该模式:

>>> a = list(re.finditer(r'(?P<name>\w+)|(?P<number>\d+)', 'Ala ma kota'))
>>> a[0]
<_sre.SRE_Match object at 0x100264ad0>
>>> a[0].re.groupindex
{'name': 1, 'number': 2}
Run Code Online (Sandbox Code Playgroud)

如果您想知道匹配的组是什么,请查看该值; None表示从未在比赛中使用的组:

>>> a[0].groupdict()
{'name': 'Ala', 'number': None}
Run Code Online (Sandbox Code Playgroud)

number组从未用于匹配任何东西,因为它的价值是None.

然后,您可以使用以下命令查找正则表达式中使用的名称:

names_used = [name for name, value in matchobj.groupdict().iteritems() if value is not None]
Run Code Online (Sandbox Code Playgroud)

或者如果只有一个组可以匹配,您可以使用MatchObject.lastgroup:

name_used = matchobj.lastgroup
Run Code Online (Sandbox Code Playgroud)

作为旁注,你的正则表达有一个致命的缺陷; \d匹配的一切,也匹配\w.你永远不会看到number用在哪里name可以先匹配.反转模式以避免这种情况:

>>> for match in re.finditer(r'(?P<name>\w+)|(?P<number>\d+)', 'word 42'):
...     print match.lastgroup
... 
name
name
>>> for match in re.finditer(r'(?P<number>\d+)|(?P<name>\w+)', 'word 42'):
...     print match.lastgroup
... 
name
number
Run Code Online (Sandbox Code Playgroud)

但是考虑到以数字开头的单词仍然会混淆你的简单案例:

>>> for match in re.finditer(r'(?P<number>\d+)|(?P<name>\w+)', 'word42 42word'):
...     print match.lastgroup, repr(match.group(0))
... 
name 'word42'
number '42'
name 'word'
Run Code Online (Sandbox Code Playgroud)


小智 5

首先,您的正则表达式在语法上是错误的:您应将其写为r'(?P<name>\w+)|(?P<number>\d+)'。而且,即使该reg expr也无法正常工作,因为特殊序列会\w匹配所有字母数字字符,因此也会匹配所有由匹配的字符\d。您应该将其更改r'(?P<number>\d+)|(?P<name>\w+)'\d优先于\w。但是,您可以使用lastgroup匹配对象的属性来获取匹配组的名称,即: [m.lastgroup for m in re.finditer(r'(?P<number>\d+)|(?P<name>\w+)', 'Ala ma 123 kota')] 产生: ['name', 'name', 'number', 'name']