Search code examples
javaregexreplaceall

Matching a whole word with leading or trailing special symbols like dollar in a string


I can replace dollar signs by using Matcher.quoteReplacement. I can replace words by adding boundary characters:

from = "\\b" + from + "\\b"; 
outString = line.replaceAll(from, to);

But I can't seem to combine them to replace words with dollar signs.

Here's an example. I am trying to replace "$temp4" (NOT $temp40) with "register1".

        String line = "add, $temp4, $temp40, 42";
        String to = "register1";
        String from = "$temp4";
        String outString;


        from = Matcher.quoteReplacement(from);
        from = "\\b" + from + "\\b";  //do whole word replacement

        outString = line.replaceAll(from, to);
        System.out.println(outString);

Outputs

"add, $temp4, $temp40, 42"

How do I get it to replace $temp4 and only $temp4?


Solution

  • Use unambiguous word boundaries, (?<!\w) and (?!\w), instead of \b that are context dependent:

    from = "(?<!\\w)" + Pattern.quote(from) + "(?!\\w)";
    

    See the regex demo.

    The (?<!\w) is a negative lookbehind that fails the match if there is a non-word char immediately to the left of the current location and (?!\w) is a negative lookahead that fails the match if there is a non-word char immediately to the right of the current location. The Pattern.quote(from) is necessary to escape any special chars in the from variable.

    See the Java demo:

    String line = "add, $temp4, $temp40, 42";
    String to = "register1";
    String from = "$temp4";
    String outString;
    
    from = "(?<!\\w)" + Pattern.quote(from) + "(?!\\w)";
    
    outString = line.replaceAll(from, to);
    System.out.println(outString);
    // => add, register1, $temp40, 42