Java String.replace匹配子串问题:如何替换完整字符串
问题根源与解决方案
你的问题出在String.replace()的匹配逻辑和代码的业务逻辑两个层面:
1. 直接原因:String.replace()是子串匹配而非整词/完全匹配
String.replace(CharSequence target, CharSequence replacement)会替换字符串中所有出现的target子串,而非只匹配完整的目标字符串。在你的例子中,"rule.10"包含"rule.1"这个子串,所以replace会把"rule.1"部分替换成isRuleLabelSuccess("rule.1"),剩下的"0"被保留,最终拼接后就得到了!(isRuleLabelSuccess("rule.1")0)。
2. 业务逻辑偏差:你实际想做的是包装predicate而非替换label子串
从你期望的输出!(isRuleLabelSuccess("rule.10"))来看,你的真实需求应该是把传入的predicate参数直接包装成isRuleLabelSuccess函数调用,而不是用label去替换predicate里的内容。你的代码错误地用label作为替换目标,导致了错误的替换结果。
修正后的代码(匹配你的期望输出)
import java.text.MessageFormat; import static java.text.MessageFormat.format; public class A { private static String buildExprByField(String label,String predicate) { // 直接将predicate包装成目标函数调用,而非替换label子串 String expression = format("isRuleLabelSuccess(\"{0}\")", predicate); expression = "!(" + expression + ")"; return expression; } public static void main(String[] args) { System.out.println(buildExprByField("rule.1","rule.10")); } }
如果你确实需要整词替换label的场景
如果你的真实需求是替换predicate中所有完整匹配label的内容(而非子串),可以使用正则表达式的整词匹配,同时注意转义label中的特殊字符(比如.在正则中是通配符):
import java.util.regex.Pattern; import java.text.MessageFormat; import static java.text.MessageFormat.format; public class A { private static String buildExprByField(String label,String predicate) { // 转义label中的正则特殊字符,避免匹配出错 String escapedLabel = Pattern.quote(label); // 使用\b表示单词边界,实现整词匹配替换 String expression = predicate.replaceAll("\\b" + escapedLabel + "\\b", format("isRuleLabelSuccess(\"{0}\")", label)); expression = "!(" + expression + ")"; return expression; } public static void main(String[] args) { // 示例:当predicate是"rule.1 and rule.10"时,只会替换"rule.1" System.out.println(buildExprByField("rule.1","rule.1 and rule.10")); // 输出:!(isRuleLabelSuccess("rule.1") and rule.10) } }
内容的提问来源于stack exchange,提问作者Biswajit
相关产品推荐
相关产品推荐

