How, exactly, do you replace groups while appending them to a string buffer? For Example: (a)(b)(c) How can you replace group 1 with d, group 2 with e and so on? I'm working with the Java regex engine. Thanks in advance.
Asked
Active
Viewed 3,485 times
3
-
1possible duplicate of [Can I replace groups in Java regex?](http://stackoverflow.com/questions/988655/can-i-replace-groups-in-java-regex) – Marcel Stör Jan 07 '14 at 20:52
3 Answers
6
You could use Matcher's
appendReplacement
Here is an example sample using:
input: "hello bob How is your cat?"
regular expression: "(bob|cat)"
output: "hello alice How is your dog"
public static void main(String[] args) {
Pattern p = Pattern.compile("(bob|cat)");
Matcher m = p.matcher("hello bob How is your cat?");
StringBuffer s = new StringBuffer();
while (m.find()) {
m.appendReplacement(s, doReplace(m.group(1)));
}
m.appendTail(s);
System.out.println(s.toString());
}
public static String doReplace(String s) {
if(s.equals("bob")) {
return "alice";
}
if(s.equals("cat")) {
return "dog";
}
return "";
}

Alan Moore
- 73,866
- 12
- 100
- 156

gtgaxiola
- 9,241
- 5
- 42
- 64
-
1+1, but you forgot to finish it off by calling `appendTail()`. I fixed it. – Alan Moore Jan 07 '14 at 21:41
1
Are you looking for something like this?
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Program1 {
public static void main(String[] args) {
Pattern p = Pattern.compile("(a)(b)(c)");
String str = "111abc222abc333";
String out = null;
Matcher m = p.matcher(str);
out = m.replaceAll("z$3y$2x$1");
System.out.println(out);
}
}
This gives 111zcybxa222zcybxa333
as output.
I guess you will see what this example does.
But OK, I think there's no ready built-in
method through which you can say e.g.:
- replace group 3 with zzz
- replace group 2 with yyy
- replace group 1 with xxx

peter.petrov
- 38,363
- 16
- 94
- 159
-
Wouldn't it be nice to have lambdas for this kind of case? Then, you could run those lambdas through a little loop, and even utilize hash maps to store regex groups as keys and their replacement patterns as values! Hurry up JDK 8! – Jesus Kevin Morales Jan 07 '14 at 21:06
-
You don't need to call `find()` before doing the replacement. If there are no matches, `replaceAll()` simply returns the original string. – Alan Moore Jan 07 '14 at 21:46
-
1
You could use Matcher#start(group)
and Matcher#end(group)
to build a generic replacement method:
public static String replaceGroup(String regex, String source, int groupToReplace, String replacement) {
return replaceGroup(regex, source, groupToReplace, 1, replacement);
}
public static String replaceGroup(String regex, String source, int groupToReplace, int groupOccurrence, String replacement) {
Matcher m = Pattern.compile(regex).matcher(source);
for (int i = 0; i < groupOccurrence; i++)
if (!m.find()) return source; // pattern not met, may also throw an exception here
return new StringBuilder(source).replace(m.start(groupToReplace), m.end(groupToReplace), replacement).toString();
}
public static void main(String[] args) {
// replace with "%" what was matched by group 1
// input: aaa123ccc
// output: %123ccc
System.out.println(replaceGroup("([a-z]+)([0-9]+)([a-z]+)", "aaa123ccc", 1, "%"));
// replace with "!!!" what was matched the 4th time by the group 2
// input: a1b2c3d4e5
// output: a1b2c3d!!!e5
System.out.println(replaceGroup("([a-z])(\\d)", "a1b2c3d4e5", 2, 4, "!!!"));
}
Check online demo here.

acdcjunior
- 132,397
- 37
- 331
- 304
-
That's much more complicated than it needs to be. See [gtgaxiola's answer](http://stackoverflow.com/a/20981946/20938). – Alan Moore Jan 07 '14 at 21:49
-
@AlanMoore `appendReplacement()` is an elegant solution for the cases where a simple replacement would suffice. Even still, for that case, I don't think my solution is complicated. Nevertheless, the method `replaceGroup()` solves a much more elaborated problem than simply replacing -- and in a generic, parameterized, way. Try achieving the results on my sample `main()` with the other and you'll get what I mean. – acdcjunior Jan 07 '14 at 22:06
-
I think I may have found another solution as well. I'm trying to see if switch statements could help us out somehow. – Jesus Kevin Morales Jan 07 '14 at 23:44