I’m trying to find a solution for this matter. I have list of characters that needs to be replaced with particular character that is mapped with the original character.
Ex : I have character map which hold the characters and it’s replacement value. Character Map :
Map<String, String> characterMap = new HashMap<String, String>(); characterMap.put("&", "x26"); characterMap.put("^", "x5e");
String that needs to be replaced : String hello = "Hello& World^";
I want replace hello string with the values in the map. This map is created from the property file and it is dynamic.
Can I achieve this by a regex ? Can I achieve this without iterating the character map ?
Advertisement
Answer
You may use this code:
Map<String, String> characterMap = new HashMap<>(); characterMap.put("&", "\x26"); characterMap.put("^", "\x5e"); String hello = "Hello& World^"; Pattern.compile("\W").matcher(hello).replaceAll( m -> characterMap.getOrDefault(m.group(), m.group()) .replaceAll("\\", "$0$0"));
Output:
"Hello\x26 World\x5e"
Details:
- In main regex we match
\W
which will match any non-word - We extract value of each matched non-word character from
characterMap
or if that key is not found we get same character back. - We call
.replaceAll("\\", "$0$0")
on extracted value to get right escaping (assuming values are just using single escaping).$0
is the complete string we match in regex here which is\\
and by using$0$0
we make it\\\\
.
Another optimized way of doing this is to construct regex using keys of your map like this:
Pattern p = Pattern.compile(characterMap.keySet().stream() .map(s -> Pattern.quote(s)).collect(Collectors.joining("|"))); // then use it with . getOrDefault p.matcher(hello).replaceAll(m -> characterMap.get(m.group()).replaceAll("\\", "$0$0")); // => "Hello\x26 World\x5e"