Python 按一行中的顺序获取命名组的范围

Python 按一行中的顺序获取命名组的范围,python,regex,Python,Regex,我有一个这样的正则表达式r'(?p)|\s+(?p)|(?p)\s+”(示例正则表达式不是实际的正则表达式),我希望按顺序获得捕获的组的跨度 例如: 1. [match.span()for match in re.finditer(regex,string)]按顺序返回跨度,但给出整个匹配的跨度,而不仅仅是捕获的组。 2. [match.span('mark1')for match in re.finditer(regex,string)]按捕获组的顺序返回跨度,但将(-1,-1)放入其他命名组

我有一个这样的正则表达式
r'(?p)|\s+(?p)|(?p)\s+”
(示例正则表达式不是实际的正则表达式),我希望按顺序获得捕获的组的跨度

例如:
1.
[match.span()for match in re.finditer(regex,string)]
按顺序返回跨度,但给出整个匹配的跨度,而不仅仅是捕获的组。
2.
[match.span('mark1')for match in re.finditer(regex,string)]
按捕获组的顺序返回跨度,但将
(-1,-1)
放入其他命名组

那么,我可以按照一行中匹配的顺序获得命名组的跨度吗,就像上面的查询一样简单

我找到了以下方法:
[match.span(name)表示在re.finditer(regex,string)中的match,如果值不是None,则match.groupdict().items()中的name和value表示在match.groupdict()中的match]

有简单的吗

下面是一个演示我的场景的示例:

import re
s = "asfasdf      32392  ..///?%        aslf    /././/               342"
reg = r'(?P<mark1>[a-z]+)|\s+(?P<mark2>[0-9]+)|(?P<mark3>[./?%]+)\s+'
print([match.span(name) for match in re.finditer(reg, s) for name, value in match.groupdict().items() if value is not None])
print([match.span() for match in re.finditer(reg, s)])
print
print([match.span('mark1') for match in re.finditer(reg, s)])
print([match.span('mark2') for match in re.finditer(reg, s)])
print([match.span('mark3') for match in re.finditer(reg, s)])
幸运的是,它有一个解决方案,您不必多次运行finditer。关于当前问题,代码为:

s = "asfasdf      32392  ..///?%        aslf    /././/               342"
reg = r'(?P<mark1>[a-z]+)|\s+(?P<mark2>[0-9]+)|(?P<mark3>[./?%]+)\s+'
p = re.compile(reg, re.IGNORECASE)
for m in re.finditer(p,s):
    for key,value in m.groupdict().items():
        if value is not None:
            print(key, m.span(key))
s=“asfasdf 32392..//?%aslf///342”
reg=r'(?P[a-z]+)|\s+(?P[0-9]+)|(?P[./?%]+)\s++'
p=重新编译(注册,重新注册)
对于m in re.finditer(p,s):
对于键,m.groupdict()中的值。items()
如果值不是“无”:
打印(键,m.span(键))

而且dict排序不再是一个问题,因为Python 3.6应该可以看到目标字符串。没有它很混乱我对你的模式有点困惑。所有捕获组的长度均为零,因此第一个组将始终匹配。@Aminah Nuraini这里有三个正则表达式分析器,它们之间用
|
分隔,目标字符串包含至少一个正则表达式分析器匹配的字符。比如说,一个正则表达式解析器匹配小写字母、其他数字和其他特殊字符……目标字符串是
“asfasdf 32392..//?%aslf///342”
@DisplayName谢谢!完成。不可能使用更简单正确的方法。关键是
re.finditer
总是返回从整个匹配开始的所有匹配(然后是捕获组)。我没有听说过finditer的任何重写版本
re.findall
不返回匹配对象:(我用上面给出的示例尝试了你的代码,匹配对象“m”只匹配了这个:因此它给出了错误的输出:mark2(-1,-1)mark1(0,7)mark3(-1)谢谢你的评论,你是对的。我已经用re.finditer更新了代码(一次)而不是。*re.match*虽然没有那么直截了当,但仍然可行。希望你同意!嗨,对不起,如果你看到我的问题,我实际上已经提到了这个解决方案,尽管它是以列表理解的形式出现的。谢谢你抽出时间!
s = "asfasdf      32392  ..///?%        aslf    /././/               342"
reg = r'(?P<mark1>[a-z]+)|\s+(?P<mark2>[0-9]+)|(?P<mark3>[./?%]+)\s+'
p = re.compile(reg, re.IGNORECASE)
for m in re.finditer(p,s):
    for key,value in m.groupdict().items():
        if value is not None:
            print(key, m.span(key))