3

I am trying to replace all digits with {digit}, but the issue is double digits are getting replaced incorrectly.

For eg:

String str = '1 AND 2 OR (3)';
Pattern p = Pattern.compile('([0-9]+)');
Matcher m = p.matcher(str);
while(m.find()) {
    Integer value = Integer.valueOf(m.group(0));
    str = str.replace(String.valueOf(value), '{'+value+'}');
}

System.debug(str);

Output:

21:39:00.24 (31729762)|USER_DEBUG|[9]|DEBUG|{1} AND {2} OR ({3})

But when there is a double digit, it does not get replaced properly.

String str = '1 AND 2 OR (13)';
Pattern p = Pattern.compile('([0-9]+)');
Matcher m = p.matcher(str);
while(m.find()) {
    Integer value = Integer.valueOf(m.group(0));
    str = str.replace(String.valueOf(value), '{'+value+'}');
}

System.debug(str);

Output: 21:39:52.28 (36494477)|USER_DEBUG|[9]|DEBUG|{1} AND {2} OR ({1}3)

I tried this too Pattern.compile('([0-9]+){1,2}'); but not successful.

Is there a way to compile a regex to consider single and double digits too?

1 Answer 1

3

It's because of how you're using replace.

If you step through this, your string becomes:

1 AND 2 OR (13) // Matches 1 in two places
{1} AND 2 OR ({1}3) // Matches 2 once
{1} AND {2} OR ({1}3) // 13 doesn't match {1}3

Instead, use replaceAll:

String str = '1 AND 2 OR (13)';
str = str.replaceAll('(\\d+)', '{$1}');
System.debug(str);

Where $1 means "use the first capture group here." Unlike replace, replaceAll uses a regular expression to begin with, so you don't need to compile, unless you're running into problems somehow.

If you absolutely need to compile, you'll want to do something like:

String str = '1 AND 2 OR (13)';
String[] buffer = new String[0];
Pattern p = Pattern.compile('(\\d*)(\\D*)');
Matcher m = p.matcher(str);
while(m.find()) {
    String group1 = m.group(1);
    String group2 = m.group(2);
    if(group1 != '') {
        group1 = '{'+group1+'}';
    }
    buffer.add(group1);
    buffer.add(group2);
}
str = String.join(buffer,'');
System.debug(str);
1
  • Oh yes, thanks for the explanation. group is the key here. But frankly speaking '{$1}' I was not even aware works in apex. Sep 6, 2022 at 16:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.