Python 非贪婪正则表达式清理 XML
我有一个“xml文件”,里面有一些不想要的字符。
<data>
<tag>blar </tag><tagTwo> bo </tagTwo>
some extra
characters not enclosed that I want to remove
<anothertag>bbb</anothertag>
</data>
我以为下面这个非贪婪的替换可以去掉那些没有正确包裹在<sometag></sometag>
里的字符。
re.sub("</([a-zA-Z]+)>.*?<","</\\1><",text)
^ ^ ^ ^ text is the xml txt.
remember tag, | | put tag back without and reopen next tag
read everything until the next '<' (non-gready)
这个正则表达式似乎只找到了</tag>[[]]<tagTwo>
中用[[]]
表示的位置。我哪里做错了呢?
编辑: 问这个问题的原因已经解决了(见评论,我的xml文件里有一个多余的&符号,导致它无法解析——这和我想删除的字符没有关系)。不过,我还是想知道这个正则表达式是否可行(以及我尝试时哪里出错),所以我没有删掉这个问题。
2 个回答
1
"</[^>]+?>[^<>]+?<"
In [1]: a="<data> <tag>blar </tag><tagTwo> bo </tagTwo> some extra characters not enclosed that I want to remove <anothertag>bbb</anothertag></data>"
In [2]: import re
In [3]: re.sub( "(</[^>]+?>)[^<>]+?<" ,"\\1<",a)
Out[3]: '<data> <tag>blar </tag><tagTwo> bo </tagTwo><anothertag>bbb</anothertag></data>'
在ipython中:
3
点号在正则表达式中默认是不能匹配换行符的,除非你加上 re.DOTALL
这个标志。
re.sub("</([a-zA-Z]+)>.*?<","</\\1><",text, flags=re.DOTALL)
这样应该没问题。(如果不行,那就是我的 Python 有问题,不是正则表达式的问题,请纠正我。)
我觉得在定义要重复的字符类时,尽量精确是个好习惯。这可以帮助避免出现 灾难性的回溯。所以,我会用 [^<]*
来代替 .*?
,这样还可以找到最后一个标签后面的多余字符。这样就不需要再加 re.DOTALL
这个标志了,因为 [^<]
是可以匹配换行符的。