在 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(""));
您将需要:
- 要设置标志
s
以启用 dotall mode
,因为它是多行内容,所以我们希望该点也覆盖行终止符,
- 那么您将需要使用
Pattern.quote(String)
来引用您的模式和
- 最后用第一个捕获组替换整个表达式,对应于
<!--
和 -->
之间的内容。
注意: 一旦取消注释,此表达式将阻止您的 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" />
我的 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(""));
您将需要:
- 要设置标志
s
以启用dotall mode
,因为它是多行内容,所以我们希望该点也覆盖行终止符, - 那么您将需要使用
Pattern.quote(String)
来引用您的模式和 - 最后用第一个捕获组替换整个表达式,对应于
<!--
和-->
之间的内容。
注意: 一旦取消注释,此表达式将阻止您的 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" />