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
