Python非贪婪正则表达式来清理xml

发布于 2024-12-08 13:38:17 字数 840 浏览 3 评论 0原文

我有一个“xml 文件”文件,其中包含一些不需要的字符,

<data>
  <tag>blar </tag><tagTwo> bo </tagTwo>
  some extra 
  characters not enclosed that I want to remove
  <anothertag>bbb</anothertag>
</data>

非贪婪替换会删除 中未正确封装的字符

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) 

我认为以下 正则表达式似乎只能找到 [[]][[]] 指示的位置 我做错了什么?

编辑: 这个问题的动机已经解决了(请参阅评论,我在 xml 文件中有一个杂散 & 导致它无法解析 - 它与我想要删除的字符无关)。但是,我仍然很好奇正则表达式是否可行(以及我的尝试出了什么问题),所以我不删除这个问题。

I have an 'xml file' file that has some unwanted characters in it

<data>
  <tag>blar </tag><tagTwo> bo </tagTwo>
  some extra 
  characters not enclosed that I want to remove
  <anothertag>bbb</anothertag>
</data>

I thought the following non-greedy substitution would remove the characters that were not properly encased in <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) 

This regex seems only to find the position indicated with the [[]] in </tag>[[]]<tagTwo>
What am I doing wrong?

EDIT:
The motivation for this question has been solved (see comments, I had a stray & in the xml file which was causing it not to parse - it had nothing to do with the characters that I want to delete). However, I am still curious as to whether the regex is possible (and what was wrong with my attempt) and so I don't delete the question.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

指尖微凉心微凉 2024-12-15 13:38:17

除非您指定 re.DOTALL 标志,否则点不匹配换行符。

re.sub("</([a-zA-Z]+)>.*?<","</\\1><",text, flags=re.DOTALL)

应该可以正常工作。 (如果不是,则说明是我的 python 出错,而不是正则表达式。请更正。)

我认为在定义要重复的字符类时尽可能精确是一个很好的做法。这有助于防止灾难性回溯。因此,我会使用 [^<]* 而不是 .*? ,还有一个额外的好处,它现在可以在最后一个标记之后找到杂散字符。这不再需要 re.DOTALL 标志,因为 [^<] 确实匹配换行符。

The dot does not match newlines unless you specify the re.DOTALL flag.

re.sub("</([a-zA-Z]+)>.*?<","</\\1><",text, flags=re.DOTALL)

should work fine. (If it does not, my python is at fault, not the regex. Please correct.)

I think it is good practise to be as precise as possible when defining character classes that are to be repeated. This helps to prevent catastrophic backtracking. Therefore, I'd use [^<]* instead of .*? with the added bonus that it now finds stray characters after the last tag. This would not need the re.DOTALL flag any longer, since [^<] does match newlines.

↙温凉少女 2024-12-15 13:38:17
 "</[^>]+?>[^<>]+?<" 

在 ipython 中:

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>'
 "</[^>]+?>[^<>]+?<" 

in ipython:

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>'
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文