Python按标签正则表达式分割

4

我想要分割这些行:

<label>Olympic Games</label>
<title>Next stop</title>

到:

["<label>", "Olympic Games", "</label>"]
["<title>", "Next stop", "</title>"]

在Python中,我可以使用正则表达式,但我所创建的内容没有任何作用:

line.split("<\*>")

1
这是XML吗?为什么不使用XML解析器? - Steven Rumbalski
除了 @StevenRumbalski 之外,必须注意这是一个坏主意,因为正则表达式缺乏足够的能力来准确解释无上下文语法(例如 XML、HTML、平衡括号)。你已经被警告了。 - Jared Smith
4个回答

4
使用lookaround和捕获组来保留分割后的文本:
使用lookaround和捕获组可以在分割字符串后保留特定的文本。
re.split(r'(?<=>)(.+?)(?=<)', '<label>Olympic Games</label>')

最好使用环视吗?我已经在regexpal中尝试了你的正则表达式,但它既不支持JavaScript也不支持PCRE。 - Alejandro Alcalde
1
@algui91 这在JS中不起作用,因为它使用了后顾,但在PCRE中应该可以工作。无论如何,很难说它是否更好,这将取决于OP将在其上使用的确切文本。速度或内存消耗不会有显着差异,但可能您的模式将匹配我的模式无法匹配的字符串,反之亦然。 - Aran-Fey

3
这个正则表达式对我来说是有效的:
<(label|title)>([^<]*)</(label|title)>

或者,正如所建议的那样:
<(label|title)>([^<]*)</(\1)>

在这里输入图片描述

我使用过http://www.regexpal.com/

我使用了三个捕获组,如果您不需要它们,只需删除 ()

您的正则表达式 <\*> 的问题在于它只匹配一个内容:<*>。您使用 \* 转义了 *,因此您表示的是:

  • 匹配任何文本,其中包含 <,然后是一个 *,最后是一个 >

2
<(label|title)>([^<]*)</(\1)> 更好。 - cwallenpoole
@cwallenpoole 你是对的,这样更优雅了。已更新。 - Alejandro Alcalde

2

数据:

line = """<label>Olympic Games</label>
<title>Next stop</title>"""

使用具有前瞻/后顾断言的 re.findall

import re

pattern = re.compile("(<.*(?<=>))(.*)((?=</)[^>]*>)")
print re.findall(pattern, line)
# [('<label>', 'Olympic Games', '</label>'), ('<title>', 'Next stop', '</title>')]

如果没有前瞻/后顾断言,只能通过捕获组并使用 re.findall 来实现:

pattern = re.compile("(<[^>]*>)(.*)(</[^>]*>)")
print re.findall(pattern, line)
# [('<label>', 'Olympic Games', '</label>'), ('<title>', 'Next stop', '</title>')]

0

如果你不介意标点符号,这里有一个快速的非正则表达式替代方案,使用itertools.groupby

代码

import itertools as it


def split_at(iterable, pred, keep_delimter=False):
    """Return an iterable split by a delimiter."""
    if keep_delimter:
        return [list(g) for k, g in it.groupby(iterable, pred)]
    return [list(g) for k, g in it.groupby(iterable, pred) if k]

演示

>>> words = "Lorem ipsum ..., consectetur ... elit, sed do eiusmod ...".split(" ")
>>> pred = lambda x: "elit" in x
>>> split_at(words, pred, True)
[['Lorem', 'ipsum', '...,', 'consectetur', '...'],
 ['elit,'],
 ['sed', 'do', 'eiusmod', '...']]

>>> words = "Lorem ipsum ..., consectetur ... elit, sed do eiusmod ...".split(" ")
>>> pred = lambda x: "consect" in x
>>> split_at(words, pred, True)
[['Lorem', 'ipsum', '...,'],
 ['consectetur'],
 ['...', 'elit,', 'sed', 'do', 'eiusmod', '...']]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接