如何从字符串末尾向后剥离图案或单词?

时间:2014-03-18 12:07:19

标签: python xml regex string right-to-left

我有一个这样的字符串:

<foo><bar><k2><v1>aaa<b>bbb</b>ccc</v1></k2></bar><foo>

我想从字符串中删除前3个最后3个结束标记。我事先不知道标签名称。

我可以使用re.sub(r'<[^<>]+>', '', in_str, 3))删除前3个字符串。如何剥离结束标签?应该保留的是:

<v1>aaa<b>bbb</b>ccc</v1>

我知道我也许可以做正确的事情,但我实际上不希望为我的目的做xml或html解析,这是为了帮助我自己可视化某些类的xml表示。

相反,我意识到这个问题很有趣。似乎我cannot只是用正则表达式向后搜索,即。 从右到左。因为那似乎unsupported

  

如果你的意思是,找到几个最正确的匹配(类似于   rfind方法的字符串)然后不,它不是直接支持。您   可以使用re.findall()并选择最后一个匹配,但如果匹配可以   重叠这可能无法给出正确的结果。

但是.rstrip对单词并不好,也不会做出模式。

我查看了Strip HTML from strings in Python,但我只想删除 3 标签。

这里可以使用什么方法?我应该扭转字符串(丑陋本身和由于&#39;&lt;&gt;&#39; s)。做标记化(为什么不解析,然后?)?或者根据从左到右的匹配创建静态结束标记?

从字符串末尾剥离模式需遵循哪种策略?

4 个答案:

答案 0 :(得分:3)

最简单的方法是使用旧式字符串拆分并限制拆分:

in_str.split('>', 3)[-1].rsplit('<', 3)[0]

演示:

>>> in_str = '<foo><bar><k2><v1>aaa<b>bbb</b>ccc</v1></k2></bar><foo>'
>>> in_str.split('>', 3)[-1].rsplit('<', 3)[0]
'<v1>aaa<b>bbb</b>ccc</v1>'
带有限制的

str.split()str.rsplit()会将字符串从开头或结尾分割到限制时间,让您选择未分割的余数。

答案 1 :(得分:2)

您已经获得了几乎所有的解决方案。 re无法倒退,但您可以:

in_str = '<foo><bar><k2><v1>aaa<b>bbb</b>ccc</v1></k2></bar></foo>'
in_str = re.sub(r'<[^<>]+>', '', in_str, 3)
in_str = in_str[::-1]
print in_str
in_str = re.sub(r'>[^<>]+/<', '', in_str, 3)
in_str = in_str[::-1]

print in_str
<v1>aaa<b>bbb</b>ccc</v1>

请注意反向字符串的反转正则表达式,但随后它会回到正面。

当然,如前所述,使用适当的解析器会更容易:

in_str = '<foo><bar><k2><v1>aaa<b>bbb</b>ccc</v1></k2></bar></foo>'
from lxml.html import etree
ix = etree.fromstring(in_str)
print etree.tostring(ix[0][0][0])
<v1>aaa<b>bbb</b>ccc</v1>

答案 2 :(得分:1)

我会查看正则表达式并使用一个这样的模式来使用拆分

http://docs.python.org/3/library/re.html?highlight=regex#re.regex.split

答案 3 :(得分:1)

很抱歉,无法发表评论,但会将其作为答案。

in_str.split('>', 3)[-1].rsplit('<', 3)[0]将适用于给定的示例 <foo><bar><k2><v1>aaa<b>bbb</b>ccc</v1></k2></bar></foo>,但不是 <foo><bar><k2><v1>aaa<b>bbb</b>ccc</v1></k2></bar></foo><another>test</another>。 你应该意识到这一点。

要解决我提供的计数器示例,您必须跟踪标记的状态(或计数)并评估您是否匹配正确的对。