Moe
Moe

Reputation: 23

Java - Regex: Several matches in same string

I have a string: String s = "The input must be of format: '$var1$'-'$var1$'-'$var1$'".

I want to replace the text between the $ with another text, so the outcome may look on the console like:
"The input must be of format: '$REPLACED$'-'$REPLACED$'-'$REPLACED$'"

I came till s.replaceAll("\\$.+\\$", "\\$REPLACED\\$";, but that results in
"The input must be of format: '$REPLACED$'" (the first and the last $ are taken as borders).

How can I tell the regex engine, that there are several occurences and each need to be processed (=replaced)?

Thank for your help!

Edit:// Thanks for your help. The "greedy thing" was the matter. Adding a ? to the regex fixed my issue. The solution now looks like this (for those witha similar problem):
s.replaceAll("\\$.+?\\$", "\\$REPLACED\\$";

Upvotes: 0

Views: 88

Answers (3)

Pshemo
Pshemo

Reputation: 124215

+ is greedy so it will try to find maximal match. This means that [$].+[$] will match

a$b$c$e
 ^^^^^

If you want .+ to look for minimal possible match you can

  • add ? after + quantifier .+? making + reluctant

  • instead of every character (.) between $ $ accept only these that are not $ like [^$].

So try to change your regex to

s.replaceAll("\\$.+?\\$", "\\$REPLACED\\$");

or

s.replaceAll("\\$[^$]+?\\$", "\\$REPLACED\\$");   

Upvotes: 2

n.st
n.st

Reputation: 946

The effect you're experiencing is called greediness: An expression like .+ will match as many characters as possible.

Use .+? instead to make the expression ungreedy and match as few characters as possible.

Upvotes: 5

anubhava
anubhava

Reputation: 784878

This should work:

String s = "The input must be of format: '$var1$'-'$var1$'-'$var1$'";
System.out.println( s.replaceAll("\\$[^$]*\\$", "\\$REPLACED\\$") );
//=> The input must be of format: '$REPLACED$'-'$REPLACED$'-'$REPLACED$'

Using this regex: \\$[^$]*\\$ will match literal $ then string until $ is found and then followed by literal $

Upvotes: 0

Related Questions