python - 在正则表达式中查找具有相同字符串的两个匹配项

标签 python regex python-3.x

如果字符串在给定结构中出现两次(即像在 XML 解析中一样),有没有办法在正则表达式中找到它? 这段代码显然不起作用,因为它找到了第一个标签,然后找到了最后一个结束标签:

re.findall(r'<(.+)>([\s\S]*)</(.+)>', s)

那么有没有办法告诉正则表达式第三个匹配项应该与第一个相同?

完整代码:

import re

s = '''<a1>
    <a2>
        1
    </a2>
    <b2>
        52
    </b2>
    <c2>
        <a3>
            Abc
        </a3>
    </c2>
</a1>
<b1>
    21
</b1>'''

matches = re.findall(r'<(.+)>([\s\S]*)</(.+)>', s)
for match in matches:
    print(match)

结果应该是所有包含以下内容的标签:

    [('a1', '\n    <a2>\n        1\n    </a2>\n    <b2>\n        52\n    </b2>\n    <c2>\n        <a3>\n            Abc\n        </a3>\n    </c2>\n'),
     ('a2', '\n        1\n    '),
      ...]

注意:我不是在寻找完整的xml解析包。这个问题具体是关于用正则表达式解决给定的问题。

最佳答案

您可以使用 backreferences和简单的递归:

>>> def m(s):
...    matches = re.findall(r'<(.+)>([\s\S]*)</(\1)>', s)
...    for k,s2,_ in matches:
...        print (k,s2)
...        m(s2)
... 
>>> m(s)
('a1', '\n    <a2>\n  ...[dropped]...      </a3>\n    </c2>\n')
('a2', '\n        1\n    ')
('b2', '\n        52\n    ')
('c2', '\n        <a3>\n            Abc\n        </a3>\n    ')
('a3', '\n            Abc\n        ')
('b1', '\n    21\n')

更多关于 backreferences from Microsoft Docs .

已编辑

为了获得额外的乐趣,使用发电机。感谢@mrCarnivore 关于删除 if s 的建议:

>>> def m(s):
...    matches = re.findall(r'<(.+)>([\s\S]*)</(\1)>', s)
...    for k,s2,_ in matches:
...        yield (k,s2)
...        yield from m(s2)
... 
>>> for x in m(s):
...    x
... 
('a1', '\n    <a2>\ [....]     Abc\n        </a3>\n    </c2>\n')
('a2', '\n        1\n    ')
('b2', '\n        52\n    ')
('c2', '\n        <a3>\n            Abc\n        </a3>\n    ')
('a3', '\n            Abc\n        ')
('b1', '\n    21\n')

关于python - 在正则表达式中查找具有相同字符串的两个匹配项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47716948/

相关文章:

python - Pandas 获取多列的排序索引顺序

PHP 准备语句...将变量绑定(bind)为 REGEXP 中的数字范围?

java正则表达式匹配&[文本]

regex - golang 中嵌套组的正则表达式问题

Python 请求导致空白响应

python - 如何使用命令行在pytest中传递多个参数?

python - PyMySQL 无法连接到本地主机上的 MySQL

python - 如何编写一个接受列表并返回不带元音的相同列表的递归函数?

python-3.x - Keras `evaluate` 函数在不同机器上返回错误的准确度

Python 使用 input() 逐行迭代 stdin