使用 RegEx 查找两个 XML 标记之间的所有内容

Posted

技术标签:

【中文标题】使用 RegEx 查找两个 XML 标记之间的所有内容【英文标题】:Find everything between two XML tags with RegEx 【发布时间】:2012-10-25 20:24:04 【问题描述】:

RegEx 中,我想找到两个XML tags 之间的标记和所有内容,如下所示:

<primaryAddress>
    <addressLine>280 Flinders Mall</addressLine>
    <geoCodeGranularity>PROPERTY</geoCodeGranularity>
    <latitude>-19.261365</latitude>
    <longitude>146.815585</longitude>
    <postcode>4810</postcode>
    <state>QLD</state>
    <suburb>Townsville</suburb>
    <type>PHYSICAL</type>
</primaryAddress>

我想找到标签和primaryAddress 之间的所有内容,然后将其删除。

primaryAddress 标签之间的所有内容都是一个变量,但我想在收到primaryAddress 时删除整个标签和子标签。

有人知道怎么做吗?

【问题讨论】:

RegEx match open tags except Xhtml self-contained tags的可能重复 【参考方案1】:

在我们的例子中,我们收到一个String 形式的 XML,并且需要删除具有一些“特殊”字符的值,例如 &amp;&lt;&gt; 等。基本上有人可以以这种形式向我们提供 XML:

<notes>
  <note>
     <to>jenice & carl </to>
     <from>your neighbor <; </from>
  </note>
</notes>

所以我需要在 String 中找到值 jenice &amp; carlyour neighbor &lt;; 并正确转义 &amp;&lt;(否则,如果您稍后将其传递给应重命名的引擎,这是一个无效的 xml未命名)。

开始时使用正则表达式是一个相当愚蠢的想法,但它既便宜又容易。所以那些愿意和我做同样事情的勇敢的人,来吧:

    String xml = ...
    Pattern p = Pattern.compile("<(.+)>(?!\\R<)(.+)</(\\1)>");
    Matcher m = p.matcher(xml);
    String result = m.replaceAll(mr -> 
        if (mr.group(2).contains("&")) 
            return "<" + m.group(1) + ">" + m.group(2) + "+ some change" + "</" + m.group(3) + ">";
        
        return "<" + m.group(1) + ">" + mr.group(2) + "</" + m.group(3) + ">";
    );

【讨论】:

【参考方案2】:

这个方法不好用但是如果你真的想用正则表达式拆分

<primaryAddress.*>((.|\n)*?)<\/primaryAddress>

经过验证的答案返回标签,但这只是返回标签之间的值。

【讨论】:

【参考方案3】:

这可以捕获最外层的标签对,即使在侧面有属性或没有结束标签

(<!--((?!-->).)*-->|<\w*((?!\/<).)*\/>|<(?<tag>\w+)[^>]*>(?>[^<]|(?R))*<\/\k<tag>\s*>)

编辑:正如上面评论中提到的,正则表达式总是不足以解析 xml,试图修改正则表达式以适应更多情况只会使其更长但仍然无用

【讨论】:

【参考方案4】:

使用正则表达式进行 HTML/XML 解析不是一个好主意...

但是,如果你想这样做,搜索正则表达式模式

<primaryAddress>[\s\S]*?<\/primaryAddress>

并用空字符串替换它...

【讨论】:

出于好奇:为什么使用正则表达式进行 HTML/XML 解析不是一个好主意? @G_G >> ***.com/questions/1732348/… 欧米茄,我只是想获得有关正则表达式的一般信息,我只是说我使用 textmate 来回应人们标记我的问题,因为使用正则表达式是个坏主意。我知道这是一个坏主意,但我在不同的环境中使用它。 以防万一您不认识它,*? 表示匹配所有内容,直到第一次出现 &lt;/primaryAddress&gt;(非贪婪匹配)。如果您的文件中有多个 &lt;primaryAddress&gt; 元素,这一点很重要。谢谢,@Ωmega。 @Ωmega 同意正则表达式和 xml 不是最好的朋友。但是,在您的回答的帮助下,我在大约 5 秒内通过我的 IDE(IntelliJ IDEA)用空行替换了 40-50 个标签。在这些情况下,这个 regex 和 xml 会很有用。【参考方案5】:

你应该可以匹配到:/&lt;primaryAddress&gt;(.+?)&lt;\/primaryAddress&gt;/

标签之间的内容将在匹配的组中。

【讨论】:

显然,即使对于问题中的示例,它也不起作用。 .+ 与回车符不匹配。 您将使用多行标志。

以上是关于使用 RegEx 查找两个 XML 标记之间的所有内容的主要内容,如果未能解决你的问题,请参考以下文章

Regex根据子值查找所有XML值

PHP RegEx 删除两个单词之间的双空格

Regex / Python3 - re.findall() - 查找操作码之间的所有匹配项

RegEx - 在引号之间查找文本并在括号之间替换

Java Regex 检查字符串是不是包含 XML 标记

ORACLE:如何使用 regexp_like 查找两个字符之间带有单引号的字符串?