我有一个这样的字符串:
<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)。做标记化(为什么不解析,然后?)?或者根据从左到右的匹配创建静态结束标记?
从字符串末尾剥离模式需遵循哪种策略?
答案 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>
。
你应该意识到这一点。
要解决我提供的计数器示例,您必须跟踪标记的状态(或计数)并评估您是否匹配正确的对。