St.Antario
St.Antario

Reputation: 27375

How can I replace a named group's value

I have the regex

private static final String COPY_NUMBER_REGEX = ".*copy(?<copy_num>\\d+)";

And I need to replace the named group as follows:

private void setCopyNum(){
    Pattern pa = Pattern.compile(COPY_NUMBER_REGEX);
    Matcher ma = pa.matcher(template.getName());
    if(ma.find()){
        Integer numToReplace = Integer.valueOf(ma.group("copy_num")) + 1;
        //How to replace the value of the original captured group with numToReplace?
    }
}

The question is in the comment in fact. Is there something in Java Regex that allows us to replace named groups value? I mean to get a new String with a replaced value, of course. For instance:

input: Happy birthday template - copy(1)
output: Happy birthday template - copy(2)

Upvotes: 0

Views: 61

Answers (1)

Mena
Mena

Reputation: 48404

Here's a quick and dirty solution:

//                                 | preceded by "copy"
//                                 |       | named group "copynum":
//                                 |       |          | any 1+ digit
final String COPY_NUMBER_REGEX = "(?<=copy)(?<copynum>\\d+)";
// using String instead of your custom Template object
String template = "blah copy41";
Pattern pa = Pattern.compile(COPY_NUMBER_REGEX);
Matcher ma = pa.matcher(template);
StringBuffer sb = new StringBuffer();
// iterating match
while (ma.find()) {
    Integer numToReplace = Integer.valueOf(ma.group("copynum")) + 1;
    ma.appendReplacement(sb, String.valueOf(numToReplace));
}
ma.appendTail(sb);
System.out.println(sb.toString());

Output

blah copy42

Notes

  • copy_num is an invalid named group - no underscores allowed
  • The example is self-contained (would work in a main method). You'll need to adapt slightly to your context.
  • You might need to add escaped parenthesis around your named group, if you need to actually match those: "(?<=copy\\()(?<copynum>\\d+)(?=\\))"

Upvotes: 1

Related Questions