Skip to content
Advertisement

replaceFirst , Why can’t special symbols be replaced?

replaceFirst , Why can’t special symbols be replaced?

System.out.println(cal); // 1 * 1 + 1 <==== ???

package com;

import org.apache.commons.lang.StringUtils;

public class Test {

    public static void main(String[] args) {

        String cal = "[aaa] * [aaa] + [bbb]";

        int cnt = StringUtils.countMatches(cal, "[");

        String delStr = "";

        for (int i = 0; i < cnt; i++) {
            delStr = cal.substring(cal.indexOf("["), cal.indexOf("]") + 1);
            cal = cal.replaceFirst("["+delStr +"]", "1");
        }

        System.out.println(cal); // 1 * 1 + 1 <==== ???
    }
}

Advertisement

Answer

Special symbols which are used in the regular expressions need to be either escaped using or entire expression should be treated as a string literal with the help of Pattern.quote which basically surrounds the regex with the pair of Q and E.

Also, in the presented code delStr would include the pair of the square brackets, thus the replacement should occur for the regexp [[aaa]], and unexpected match — first a in the first occurrence of [aaa] — is found and replaced for such pattern instead of implied replacement. Then for the following iterations the cal looks like [1aa] * [aaa] + [bbb] and cal.indexOf("[") bring the same first occurrence several times.

So, the following escape of the special symbols described above works fine:

String delStr = "";

for (int i = 0; i < cnt; i++) {
    delStr = cal.substring(cal.indexOf("["), cal.indexOf("]") + 1);

    cal = cal.replaceFirst("\Q" + delStr + "\E", "1"); // literal mode
    // or cal = cal.replaceFirst(Pattern.quote(delStr), "1");
}

Also, this solution may be refactored to completely get rid of the loop and String::indexOf / String::replaceFirst methods, because the implied result means that all the substrings between [ and ] including the brackets should be replaced with 1, that is, String::replaceAll would do the entire job:

cal = cal.replaceAll("\[[^]]*\]", "1"); // 1 * 1 + 1
User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement