TL;DR: You want .replace
. Not .replaceAll
. Which will replace all occurrences (Yes, .replace
replaces all, as does replaceAll
) - and won't complain about dangling metacharacters.
Here's how it breaks down:
a.replace("needle", "duck")
turns all needles into ducks.
a.replaceAll("needleRegex", "duck")
parses the first string argument as a regular expression (which is a programming language-esque concept to describe regular grammars, and +
has significance in this language, hence why you got your error). Then replaces all substrings within a
that match the regex with "duck"
. .replaceAll
is the regular expression version, .replace
is the plain strings version.
a.replaceFirst("needleRegex", "duck")
is like replaceAll
, except it stops after replacing the first substring it finds.
In other words, All/First
contrast to each other, and these methods are very badly named / should never have been part of java1. The appropriate methods, if they are to exist at all, either [A] should have taken a Pattern
as first argument (java is strongly nominally typed, if there's a type that represents the thing, use it), or [B] should have been named .regexReplaceAll
instead.
As a consequence I strongly advise all to never use .replaceAll
. If you really want to futz with regular expressions (can be quite powerful, but you should want them, you don't want some code to arbitrarily apply regex parsing as a surprise), make a pattern, use its replace-all methods instead. That way, your code is more flexible (Example: If parsing the regex is part of a profiler's performance tight loop, you can isolate it. You can explicitly set parameters, and use the vast array of methods pattern/matcher expose, instead of just replaceAll/replaceFirst/matches) - and nobody will be confused when reading it: You are using regexes, it is obvious that you are, and it is obvious that you intended to.
1 Java tends to take backwards compatibility fairly seriously; as a consequence I doubt these methods will be removed or even marked as obsolete/deprecated/ill-advised, because that would break existing code. However, the ecosystem may (should!) make a move; linter tools should ship out of the box advising against it, IDEs should remove or at least visually disencourage these methods in their auto-complete dialogs, and so on.