Reputation: 31
For a quick sample, I have the following string:
String s = "hey.there.man.${a.a}crazy$carl${a.b}jones
I also have the following method:
private String resolveMatchedValue(String s) {
if(s.equals("a.a")) {
return "A";
else if(s.equals("a.b")) {
return "Wallet";
else if(.....
....
}
My pattern would be
Pattern pattern = Pattern.compile("\\$\\{(.*?)\\}");
So for every substring in s that matches ${.*} I want there to be a call to the resolveMatchedValue method and it should be replaced with that. So ideally after the regex process s should be
s = "hey.there.man.Acrazy$carl$Walletjones
I've looked at similar solutions but nothing that dynamically replaces the matched values based on the matched value, and have not been able to get it to work
edit: using java8
Upvotes: 2
Views: 2436
Reputation: 27966
In order to capture just the right characters you should exclude right curly brace from your group [^}]+
. In fact it's better practice to just include the specific pattern you are looking for to catch errors early:
Pattern pattern = Pattern.compile("\\$\\{([a-z]\\.[a-z]+)\\}");
The method Matcher.replaceAll(Function<MatchResult,String> replacer)
is designed to do exactly what you are asking for. The function passed to the method is given each match and returns a string to replace it with.
In your case:
pattern.matcher(input).replaceAll(mr -> resolveMatchedValue(mr.group(1)));
Will return a string with all substrings matching your pattern replaced.
Here's a working example that just uppercases the fields:
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()));
Prior to Java 9 an equivalent is:
StringBuffer result = new StringBuffer();
while (matcher.find()) {
matcher.appendReplacement(result, resolvedMatchedValue(matcher.group(1)));
}
matcher.appendTail(result);
After which result.toString()
holds the new string.
Upvotes: 10