Java正则表达式:将组与字符串进行比较

3
我是一个有帮助的助手,可以为您进行文本翻译。以下是您需要翻译的内容:

我正在尝试使用正则表达式进行替换。相关的代码片段如下:

String msg ="    <ClientVerificationResult>\n " +
            "      <VerificationIDCheck>Y</VerificationIDCheck>\n" +
            "    </ClientVerificationResult>\n";

String regex = "(<VerificationIDCheck>)([Y|N])(</VerificationIDCheck>)";
String replacedMsg= msg.replaceAll(regex, "$2".matches("Y") ? "$1YES$3" : "$1NO$3") ;
System.out.println(replacedMsg);

这个的输出结果是:
<ClientVerificationResult>
   <VerificationIDCheck>NO</VerificationIDCheck>
</ClientVerificationResult>

当应该这样时

<ClientVerificationResult>
   <VerificationIDCheck>YES</VerificationIDCheck>
</ClientVerificationResult>

我猜问题在于"$2".matches("Y")返回了false。我尝试过使用"$2".equals("Y")并在matches()中使用类似于"[Y]""([Y])"的奇怪组合,但仍然没有结果。
如果我打印"$2",输出是Y。请问我做错了什么吗?
2个回答

4

在使用replaceAll时,不能将Java代码作为替换参数,因为它只能是一个字符串。最好使用PatternMatcherAPI,并针对你的替换逻辑评估matcher.group(2)

建议的代码:

String msg ="    <ClientVerificationResult>\n " +
        "      <VerificationIDCheck>Y</VerificationIDCheck>\n" +
        "    </ClientVerificationResult>\n";

String regex = "(<VerificationIDCheck>)([YN])(</VerificationIDCheck>)";
Pattern p = Pattern.compile(regex);

Matcher m = p.matcher( msg );
StringBuffer sb = new StringBuffer();
while (m.find()) {
    String repl = m.group(2).matches("Y") ? "YES" : "NO";
    m.appendReplacement(sb, m.group(1) + repl + m.group(3));
}
m.appendTail(sb);
System.out.println(sb); // replaced string

1
жҲ‘д»ҘдёәжҲ‘еҸҜд»ҘиәІиҝҮдёҚдҪҝз”ЁMatcherе’ҢPatternзҡ„й—®йўҳпјҢеҸҜжғңжҲ‘й”ҷдәҶгҖӮ - Tavo
我想你可以这样做,但需要对其进行两次解析。 - Vlasec

1
您正在检查字面字符串“$2”,以查看它是否与“Y”匹配。这是不可能发生的。

据我所知,这里的"$2"会被解析为第二个组,而在这种情况下是Y - Tavo
不,你实际上没有在正则表达式的上下文中评估字符串“$2”。你正在调用matches()的是字面字符串“$2”。它是一个字符串常量,这意味着它除了“$2”之外什么都不能是。你需要先对其进行评估(请参见anubhava的答案以获取提示)。 - dcsohl
如果我执行 msg.replaceAll(regex, "$2".matches("Y") ? "$2" : "$2");System.out.println(replacedMsg); 将会打印出 <ClientVerificationResult>Y</ClientVerificationResult>。为什么它在一个地方被评估而在另一个地方没有被评估? - Tavo
1
因为你的三元表达式("$2".matches("Y") ? "$2" : "$2")返回的是"$2" - 我应该指出的是最后一个"$2",而不是中间的那个 - 然后被replaceAll()调用之前进行评估。在replaceAll()执行其操作之前,你处理的是上面所有三个位置的字面字符串"$2"。Java链接其调用并从内向外工作。首先它说“$2是否匹配Y?不,所以我将返回$2。”然后它调用replaceAll(),将此$2转换为实际匹配。 - dcsohl
是的,即使在 replaceAll(...) 调用内部,它仍然只是一个普通的 "$2" 字符串,永远不会匹配正则表达式 "Y"。因此三元表达式的条件始终返回 false。 - Vlasec

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接