use*_*097 6 python regex python-3.x
我有一个包含多个命名组的 Python 正则表达式。但是,如果之前的组匹配,则匹配一组的模式可能会被遗漏,因为似乎不允许重叠。举个例子:
import re
myText = 'sgasgAAAaoasgosaegnsBBBausgisego'
myRegex = re.compile('(?P<short>(?:AAA))|(?P<long>(?:AAA.*BBB))')
x = re.findall(myRegex,myText)
print(x)
Run Code Online (Sandbox Code Playgroud)
产生输出:
[('AAA', '')]
Run Code Online (Sandbox Code Playgroud)
“长”组找不到匹配项,因为“AAA”在为前面的“短”组查找匹配项时已用完。
我试图找到一种允许重叠但失败的方法。作为替代方案,我一直在寻找一种方法来分别运行每个命名组。类似于以下内容:
for g in myRegex.groupindex.keys():
match = re.findall(***regex_for_named_group_g***,myText)
Run Code Online (Sandbox Code Playgroud)
是否可以为每个命名组提取正则表达式?
最终,我想生成一个字典输出(或类似的),如:
{'short':'AAA',
'long':'AAAaoasgosaegnsBBB'}
Run Code Online (Sandbox Code Playgroud)
任何和所有建议将不胜感激。
确实似乎没有更好的方法来做到这一点,但这是另一种方法,类似于另一个答案类似,但稍微简单一些。它将起作用,前提是:a) 您的模式始终形成为一系列由管道分隔的命名组,并且 b) 命名组模式从不包含命名组本身。
如果您对每种模式的所有匹配感兴趣,以下将是我的方法。参数re.split寻找一个文字管道,后跟(?=<,命名组的开头。它编译每个子模式并使用groupindex属性来提取名称。
def nameToMatches(pattern, string):
result = dict()
for subpattern in re.split('\|(?=\(\?P<)', pattern):
rx = re.compile(subpattern)
name = list(rx.groupindex)[0]
result[name] = rx.findall(string)
return result
Run Code Online (Sandbox Code Playgroud)
根据给定的文本和模式,返回{'long': ['AAAaoasgosaegnsBBB'], 'short': ['AAA']}. 根本不匹配的模式的值将是一个空列表。
如果您只想每个模式匹配一次,您可以使其变得更简单:
def nameToMatch(pattern, string):
result = dict()
for subpattern in re.split('\|(?=\(\?P<)', pattern):
match = re.search(subpattern, string)
if match:
result.update(match.groupdict())
return result
Run Code Online (Sandbox Code Playgroud)
这给出了{'long': 'AAAaoasgosaegnsBBB', 'short': 'AAA'}你的给定。如果指定的组之一根本不匹配,则该组将不会出现在字典中。
| 归档时间: |
|
| 查看次数: |
2074 次 |
| 最近记录: |