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

yop*_*one 0 java regex matcher java-8

对于快速示例,我有以下字符串:

String s = "hey.there.man.${a.a}crazy$carl${a.b}jones
Run Code Online (Sandbox Code Playgroud)

我也有以下方法:

private String resolveMatchedValue(String s) {
    if(s.equals("a.a")) {
           return "A";
    else if(s.equals("a.b")) { 
           return "Wallet";
    else if(.....
    ....
 }
Run Code Online (Sandbox Code Playgroud)

我的模式是

 Pattern pattern = Pattern.compile("\\$\\{(.*?)\\}");
Run Code Online (Sandbox Code Playgroud)

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

 s = "hey.there.man.Acrazy$carl$Walletjones
Run Code Online (Sandbox Code Playgroud)

我已经查看了类似的解决方案,但没有根据匹配的值动态替换匹配的值,并且无法使其工作

编辑:使用java8

spr*_*ter 5

为了捕获正确的字符,您应该从组中排除右大括号[^}]+.实际上,最好只包括您要寻找的特定模式以及早发现错误:

Pattern pattern = Pattern.compile("\\$\\{([a-z]\\.[a-z]+)\\}");
Run Code Online (Sandbox Code Playgroud)

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

在你的情况下:

pattern.matcher(input).replaceAll(mr -> resolveMatchedValue(mr.group(1)));
Run Code Online (Sandbox Code Playgroud)

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

这是一个工作示例,只是将字段大写:

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()));
Run Code Online (Sandbox Code Playgroud)

在Java 9之前,等效的是:

StringBuffer result = new StringBuffer();
while (matcher.find()) {
    matcher.appendReplacement(result, resolvedMatchedValue(matcher.group(1)));
}
matcher.appendTail(result);
Run Code Online (Sandbox Code Playgroud)

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