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?
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
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);
$
has special meaning in regex (it means “end of input”). To remove any special meaning from characters in your target, wrap it in regex quote/unquote expressions \Q...\E
. Also, because $
is not ”word” character, the word boundary won’t wiork, so use look arounds instead:
line = line.replaceAll("(?<!\\S)\\Q" + from + "\\E(?![^ ,])", to);
Normally, Pattern.quote
is the way to go to escape characters that may be specially interpreted by the regex engine.
However, the regular expression is still incorrect, because there is no word boundary before the $
in line
; space and $
are both non-word characters. You need to place the word boundary after the $
character. There is no need for Pattern.quote
here, because you're escaping things yourself.
String from = "\\$\\btemp4\\b";
Or more simply, because you know there is a word boundary between $
and temp4
already:
String from = "\\$temp4\\b";
The from
variable can be constructed from the expression to replace. If from
has "$temp4"
, then you can escape the dollar sign and add a word boundary.
from = "\\" + from + "\\b";
Output:
add, register1, $temp40, 42