Reputation: 1927
In java I want to replace only the capturing group in the matched part with some other value and the value to be replaced depends on the capturing group.
Eg:
String str = "fname:hello hello:world ffff:off";
Map<String, String> mapping = new HashMap<String, String>();
dat.put("fname", "meme");
dat.put("hello", "below");
dat.put("ffff", "ssss");
Pattern pat = Pattern.compile("([a-zA-Z_]+):");
In the above code I want to replace the capturing group part of the pattern "pat" with the corresponding mapping found in the "mapping". i.e. After the replacement the "str" string should be transformed to "meme:hello below:world ssss:off" How can I achieve this? Thanks for the help.
Upvotes: 3
Views: 1908
Reputation: 20163
Please consider bookmarking the Stack Overflow Regular Expressions FAQ for future reference. There's a bunch of Java-specific information in there, particularly in the "Flavor-Specific Information" section.
This works:
import java.util.Map;
import java.util.HashMap;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class Replacement {
public static final void main(String[] ignored) {
String str = "fname:hello hello:world ffff:off";
Map<String, String> mapping = new HashMap<String, String>();
mapping.put("fname", "meme");
mapping.put("hello", "below");
mapping.put("ffff", "ssss");
Pattern pat = Pattern.compile("([a-zA-Z_]+):");
Matcher m = pat.matcher(str);
StringBuffer sb = new StringBuffer();
while(m.find()) {
String rplcWith = mapping.get(m.group(1));
m.appendReplacement(sb, rplcWith + ":");
}
m.appendTail(sb);
System.out.println(sb);
}
}
Output:
[C:\java_code\]java Replacement
meme:hello below:world ssss:off
Upvotes: 5
Reputation: 75545
If you are just trying to match a word if it appears before a :
, it is much easier to just create that expression and iterate over the map.
import java.util.*;
public class Main{
public static void main(String[] args) {
String str = "fname:hello hello:world ffff:off";
Map<String, String> mapping = new HashMap<String, String>();
mapping.put("fname", "meme");
mapping.put("hello", "below");
mapping.put("ffff", "ssss");
for (String key: mapping.keySet())
str = str.replace(key + ":", mapping.get(key)+":");
System.out.println(str);
}
}
This is simple but sufficient to get your desired output:
meme:hello below:world ssss:off
Upvotes: 1
Reputation: 1237
You could go through the entrySet of your map and replace all instances of the keys with their associated values
for (Entry<String, String> entry : mapping.entrySet()) {
str.replaceAll(entry.getKey(), entry.getValue();
}
However, this will have a different output string to what you're expecting because the word "hello" appears twice
So instead of meme:hello below:world ssss:off
you will get meme:below below:world ssss:off
Does that answer your question adequately or is it essential that the output is how you defined it?
Upvotes: 0