It would be easier to first create some kind of mapping between replaced character and its replacement. I mean something like
Map<String, String> map = new HashMap<>();
map.put("a", "c");
map.put("b", "d");
then you can use appendReplacement
and appendTail
from Matcher class to replace matched character. Deciding on how to get replaced character can be done like map.get(matchedCharacter)
.
Simple Demo
Map<String, String> map = new HashMap<>();
map.put("a", "c");
map.put("b", "d");
String demo = "abcdef";
Pattern p = Pattern.compile("[ab]");
Matcher m = p.matcher(demo);
StringBuffer sb = new StringBuffer();
while (m.find()){
m.appendReplacement(sb, map.get(m.group()));
}
m.appendTail(sb);
String replaced = sb.toString();
System.out.println(replaced);
Output: cdcdef
UPDATE for Java 9 and above
In below template we usually change only one thing, decision about what to use as replacement of founded match.
StringBuffer sb = new StringBuffer();
while (m.find()){
m.appendReplacement(sb, /* decision about replacement*/ );
// ^^^^^^^^^^^^^^^^^^^^^^^^^^
}
m.appendTail(sb);
String replaced = sb.toString();
So since rest of that logic is repeated, this template was wrapped as String replaceAll(Function<MatchResult,String> replacer)
which require from us to provide logic of obtaining replacement for founded match. So above code can be reduced to:
Map<String, String> map = new HashMap<>();
map.put("a", "c");
map.put("b", "d");
String demo = "abcdef";
Pattern p = Pattern.compile("[ab]");
Matcher m = p.matcher(demo);
String replaced = m.replaceAll(match -> map.get(match.group()));
System.out.println(replaced);