Java匹配器如何根据组的值动态替换组

标签 java regex java-8 matcher

作为一个快速示例,我有以下字符串:

String s = "hey.there.man.${a.a}crazy$carl${a.b}jones

我还有以下方法:

private String resolveMatchedValue(String s) {
    if(s.equals("a.a")) {
           return "A";
    else if(s.equals("a.b")) { 
           return "Wallet";
    else if(.....
    ....
 }

我的模式是

 Pattern pattern = Pattern.compile("\\$\\{(.*?)\\}");

因此,对于 s 中与 ${.*} 匹配的每个子字符串,我希望调用resolveMatchedValue 方法,并且应该将其替换为该方法。所以理想情况下,在正则表达式进程之后 s 应该是

 s = "hey.there.man.Acrazy$carl$Walletjones

我看过类似的解决方案,但没有任何解决方案可以根据匹配值动态替换匹配值,并且无法使其正常工作

编辑:使用java8

最佳答案

为了捕获正确的字符,您应该从组中排除右大括号 [^}]+ 。事实上,更好的做法是只包含您正在寻找的特定模式以尽早发现错误:

Pattern pattern = Pattern.compile("\\$\\{([a-z]\\.[a-z]+)\\}");

方法Matcher.replaceAll​(Function<MatchResult,String> replacer)旨在完全满足您的要求。传递给该方法的函数会给出每个匹配项,并返回一个字符串来替换它。

就您而言:

pattern.matcher(input).replaceAll(mr -> resolveMatchedValue(mr.group(1)));

将返回一个字符串,其中所有与您的模式匹配的子字符串都被替换。

这是一个仅将字段大写的工作示例:

System.out.println(Pattern.compile("\\$\\{([[a-z]\\.[a-z])\\}")
    .matcher("hey.there.man.${a.a}crazy$carl${a.b}jones")
    .replaceAll(mr -> mr.group(1).toUpperCase()));
<小时/>

在 Java 9 之前,等效项是:

StringBuffer result = new StringBuffer();
while (matcher.find()) {
    matcher.appendReplacement(result, resolvedMatchedValue(matcher.group(1)));
}
matcher.appendTail(result);

之后result.toString()保存新字符串。

关于Java匹配器如何根据组的值动态替换组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50321341/

相关文章:

java - 在 Java 或 Python 中使用正则表达式灵活解析文本

java - 如何让Java编译器在编译后的代码中生成行号

java - 如何检查OrientDB服务器是否正在创建/重建不稳定性?

java - 使用 Java 8 流减小列表的大小

java-8 - 基于多个值对 map 进行排序(Java8/Jooq)

Java8过滤并返回如果只有元素

Java:读取事先不知道类型的数据

python - 用python re剥离变量边界

Javascript JSON对象替换对象内的字符串

java.util.regex