在 Java 中通过正则表达式取消注释 XML 元素

Uncomment an XML element through regex in Java

我的 XML 如下所示,

<!-- Service Defs -->

<!-- <serviceName = "${NASA_Freedom.level.mission}"
                 MaxTimeOut = "20" minSpareHyperThread = "10" />
-->

我只需要取消对 serviceName 元素的注释:

<serviceName = "${NASA_Freedom.level.mission}"
                 MaxTimeOut = "20" minSpareHyperThread = "10" />

以下代码似乎无法解决问题:

Pattern p = Pattern.compile("(<!--).*<serviceName = \"${NASA_Freedom.*(-->)");
Matcher m = p.matcher(test);
if (m.find()) {
    System.out.println(m.replaceAll(""));
}

这似乎也是一种糟糕的处理方式。不幸的是,我无法对 XML 文件做任何事情,所以这似乎是唯一的方法。我如何取消上面的评论?

尝试使用这个正则表达式:

<!--\s*(<serviceName\s*=\s*\"${NASA_Freedom.level.mission}\".*?)\s*-->

正确转义引号等字符非常重要,这样您的 Java 语法才有效。

您需要使用 Pattern.DOTALL 作为 Pattern.compile 的参数,这样模式将匹配多行(基本上告诉正则表达式引擎将 . 与换行符匹配).

Pattern p = Pattern.compile("<!--\s*(<serviceName\s*=\s*\"${NASA_Freedom.level.mission}\".*?)\s*-->", Pattern.DOTALL);

如果您用捕获组 1 的内容替换每个匹配项,它应该删除注释。

编辑:

如果您更喜欢匹配注释并通过用空字符串替换它们来删除它们,请改用此正则表达式:

(<!--\s*)<serviceName\s*=\s*\"${NASA_Freedom.level.mission}\".*?(\s*-->)

基本上只是反转第一个正则表达式的分组。

要取消对给定模式的注释,您可以按下一步进行:

Pattern p = Pattern.compile(
    "(?s)<!--(.*" + 
     Pattern.quote("<serviceName = \"${NASA_Freedom.level.mission}\"") + 
    "((?!-->).)*)-->"
);
System.out.println(p.matcher(xml).replaceAll(""));

您将需要:

  1. 要设置标志 s 以启用 dotall mode,因为它是多行内容,所以我们希望该点也覆盖行终止符,
  2. 那么您将需要使用 Pattern.quote(String) 来引用您的模式和
  3. 最后用第一个捕获组替换整个表达式,对应于 <!----> 之间的内容。

注意: 一旦取消注释,此表达式将阻止您的 XML,因为它不再是正确的格式。

NB2: 我添加了一个零宽度负前瞻以防止在捕获的组中有 --> 这样可以避免影响其他评论

这是一种方式

查找:"<!--(?:(?!-->)[\S\s])*?(<serviceName\s+(?:(?:(?:\"[\S\s]*?\")|(?:'[\S\s]*?'))|(?:[^>]*?))+\s*/>)[\S\s]*?-->"

替换:""基本上用字符串中的第 1 组替换第 0 组

展开:

 <!-- 
 (?:
      (?! --> )
      [\S\s] 
 )*?

 (                             # (1 start)
      <serviceName \s+ 
      (?:
           (?:
                (?: " [\S\s]*? " )
             |  (?: ' [\S\s]*? ' )
           )
        |  (?: [^>]*? )
      )+
      \s* />
 )                             # (1 end)

 [\S\s]*? -->

输入:

<!-- Service Defs -->

<!-- <serviceName = "${NASA_Freedom.level.mission}"
                 MaxTimeOut = "20" minSpareHyperThread = "10" />
-->

输出:

 **  Grp 0 -  ( pos 25 , len 122 ) 
<!-- <serviceName = "${NASA_Freedom.level.mission}"
                 MaxTimeOut = "20" minSpareHyperThread = "10" />
-->  
 **  Grp 1 -  ( pos 30 , len 112 ) 
<serviceName = "${NASA_Freedom.level.mission}"
                 MaxTimeOut = "20" minSpareHyperThread = "10" />