Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 313
john ktejik Avatar asked Apr 17 '18 23:04

john ktejik


2 Answers

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
like image 160
Wiktor Stribiżew Avatar answered Sep 28 '22 05:09

Wiktor Stribiżew


Matcher.quoteReplacement() is for the replacement string (to), not the regex (from). To include a string literal in the regex, use Pattern.quote():

from = Pattern.quote(from);
like image 20
shmosel Avatar answered Sep 28 '22 07:09

shmosel