Python正则表达式匹配顺序html标签

时间:2014-01-23 12:03:39

标签: python html regex

我正在尝试仅匹配html片段中特定标记的连续出现。 对于测试字符串“blah <em>BAD</em> blah blah blah <em>Time</em> <em>Warner</em> <em>Satan</em>. The blah ..”,我想只匹配“时间”,“华纳”和“撒旦”(作为单独的字符串或一组,无关紧要),但不是“坏”。

到目前为止,我最接近的尝试是(<em>(?P<match>.*?)</em>[\s\.]){2,},它给了我'撒旦'。至少它似乎是强制执行2或更多,但不返回该匹配中的所有内容。我猜测一个涉及积极前瞻的解决方案是我需要的,但我似乎无法随意使用。

我查看了其他各种相关问题,但似乎找不到合适的解决方案。大多数相关问题只是填充了答案,说明HTML永远不应该使用正则表达式进行解析,而不是回答问题。我对lxml / BeautifulSoup解决方案感到满意,只要它强制执行我的要求的顺序属性,但我最感兴趣的是正则表达式,即使只是从好奇的角度来看。我知道我正在寻找的东西必须是正则表达式。

感谢您的帮助和意见。

编辑:我已经意识到我可以通过使用更简单的方法来解决这个问题,方法是将标记的所有实例与<em>(?P<match>.*?)</em>匹配,迭代每个匹配对象并比较每个匹配对象的开始和结束位置比赛。它有用,但我宁愿找一个更整洁的解决方案。

1 个答案:

答案 0 :(得分:1)

如果您对重新解决方案感到好奇,可能会这样:

html = "blah <em>BAD</em> blah blah blah <em>Time</em> <em>Warner</em> <em>Satan</em>. The blah .."

rx = r"""(?x)          # extended mode - enable comments
    (                  # match a tag
        <em            # tag name
          [^<>]*       # maybe also attributes
        >              # open tag matched
        (              # now match the tag body
            (?<!</em)  # there must be no closing tag before a character
            .          # a body character
        ) *            # some more characters like this
        </em>          # closing tag
        \s*            # maybe some spaces after it
    ){2,}              # repeat the whole thing twice or more
"""

print re.sub(rx, r'{{\g<0>}}', html)
# blah <em>BAD</em> blah blah blah {{<em>Time</em> <em>Warner</em> <em>Satan</em>}}. The blah ..