【问题标题】:Find everything between two XML tags with RegEx使用 RegEx 查找两个 XML 标记之间的所有内容
【发布时间】: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 时删除整个标签和子标签。

有人知道怎么做吗?

【问题讨论】:

标签: java php regex xml perl


【解决方案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 解析不是一个好主意?
        • 欧米茄,我只是想获得有关正则表达式的一般信息,我只是说我使用 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;/

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

        【讨论】:

        • 显然,即使对于问题中的示例,它也不起作用。 .+ 与回车符不匹配。
        • 您将使用多行标志。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-06-24
        • 2018-01-06
        • 1970-01-01
        • 2020-02-05
        • 2012-12-12
        • 2021-02-07
        • 1970-01-01
        相关资源
        最近更新 更多