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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .