首先,我是stackoverflow的新手,所以如果我有任何错误,我道歉。我会尽力不再犯这些错误。
所以问题是,我正在尝试使用正则表达式来分割句子,或者使用以下格式的语料库:
outside <X TYPE='X1'> inside <X TYPE='X2'> inside </X> <X TYPE='X3'> inside </X> </X> outside.
外部和内部只是随机词(unicode); <X TYPE='X?'> </X>
是一个完整的标签,里面可以有标签。我想要的结果应该是这样的:
["outside", "<X TYPE='X1'> inside <X TYPE='X2'> inside </X> <X TYPE='X3'> inside </X> </X>", "outside"]
这意味着我想用最大的标签来分割句子(对不起我的英语)。
我所做的所有尝试只会导致最小的标签(最大标签内的标签)分裂。任何人都可以告诉我一个实现这个目标的方法吗?非常感谢你。
首先,正则表达式可能不是最好的工具,使用适当的XML解析器库可能会获得更好,更可靠的结果。但是,对于您的情况,以下似乎可以解决问题:
>>> import re
>>> text = "outside <X TYPE='X1'> inside <X TYPE='X2'> inside </X> <X TYPE='X3'> inside </X> </X> outside."
>>> re.split(r"(<.+>)", text)
['outside ',
"<X TYPE='X1'> inside <X TYPE='X2'> inside </X> <X TYPE='X3'> inside </X> </X>",
' outside.']
这将re.split
由<...>
封闭的最大字符串,并由于捕获组(...)
保留该部分。请注意,这只是分别捕获第一个和最后一个标记之前和之后的文本,但不一定是任何标记之外的文本!
>>> text2 = "outside <X> inside </X> outside, too? <X> inside again </X> outside."
>>> re.split(r"(<.+>)", text2)
['outside ',
'<X> inside </X> outside, too? <X> inside again </X>',
' outside.']
相反,如果您想要单个标签,只需将.+
更改为.+?
即可按最小的此类组进行拆分。
>>> re.split(r"(<.+?>)", text)
['outside ', "<X TYPE='X1'>", ' inside ', "<X TYPE='X2'>", ' inside ', '</X>', ' ', "<X TYPE='X3'>", ' inside ', '</X>', ' ', '</X>', ' outside.']
然后,您可以使用它来使用堆栈或简单标记计数器查找任何标记之外的文本:
parts = re.split(r"(<.+?>)", text2)
for part in parts:
if part.startswith("<"):
tags += -1 if part.startswith("</") else +1
elif tags == 0:
print(part)