2014-10-20 84 views
0

我有一个正则表达式,看起来像:提取名称和正则表达式的跨度匹配组

rgx = '(?P<foo>ABC)(?P<bar>DEF)?(?P<norf>HIJK)' 

获得匹配的字符串是没有问题的m.group(name)。但是,我需要提取名称范围的匹配组(甚至只是名称的跨度),并没有找到一种方法来做到这一点。我想这样做:

p = re.compile(p, re.IGNORECASE) 
m = p.match(targetstring) 
#then do something to set 'all' to the list of match objects 
for mo in all 
    print mo.name() + '->' + mo.span() 

因此,例如,输入字符串“ABCDEFHIJK”应该产生的输出:

'foo' -> (0, 3) 
'bar' -> (3, 6) 
'norf' -> (6, 10) 

谢谢!

+0

是什么'span'? – laike9m 2014-10-20 12:06:30

+0

发布一个示例以及预期的输出。 – 2014-10-20 12:07:24

+0

@ laike9m span是属于正则表达式MatchObject的一种方法。它告诉字符串的哪一部分是匹配的。 – Colin 2014-10-20 12:17:44

回答

3

您遍历匹配组的名称(中groupdict键)并打印相应的span属性:

rgx = '(?P<foo>ABC)(?P<bar>DEF)?(?P<norf>HIJK)' 
p = re.compile(rgx, re.IGNORECASE) 
m = re.match(p, 'ABCDEFHIJKLM') 

for key in m.groupdict(): 
    print key, m.span(key) 

此打印:

foo (0, 3) 
bar (3, 6) 
norf (6, 10) 

编辑:由于密钥的字典是无序的,你可能希望明确地选择密钥迭代的顺序。在下面的例子中,sorted(...)是相应的字典值排序的组名的列表(span元组):

for key in sorted(m.groupdict().keys(), key=m.groupdict().get): 
    print key, m.span(key) 
+0

您的代码不会打印结果。 – georg 2014-10-20 12:27:15

+0

@georg糟糕。修正了错字。谢谢! – 2014-10-20 12:28:20

+0

这样更好,但仍然没有雪茄。 'groupdict'是一个字典,所以结果的顺序是不能保证的。 – georg 2014-10-20 12:29:11

2

您可以使用RegexObject.groupindex

p = re.compile(rgx, re.IGNORECASE) 
m = p.match('ABCDEFHIJK') 

for name, n in sorted(m.re.groupindex.items(), key=lambda x: x[1]): 
    print name, m.group(n), m.span(n)