I am trying to write a regex which should detect "Is the entire string a placeholder".
An example of a valid placeholder here is ${var}
An example of an invalid palceholder here is ${var}-sometext
as the placeholder is just a part of the text
The regex I have currently is ^\$\{(. )\}$
This works for normal cases. for example
1 | ${var} | Regex Matches | Expected ✅ |
2 | ${var} txt | Regex Does Not Match | Expected ✅ |
even works for nested placeholders
3 | ${var-${nestedVar}} | Regex Matches | Expected ✅ |
Where this fails is if the strings begins and ends with a placeholder for eg
4 | ${var1}-txt-${var2} | Regex Matches | NOT Expected ❌ |
Basically even though the entire string is not a placeholder, the regex treats it as one as it begins with ${
and ends with }
I can try solving it by replacing .
with something like [^$]
to exclude dollar, but that will break the nested use case in example 3.
How do I solve this?
EDIT
Adding some code for context
public static final Pattern PATTERN = Pattern.compile("^\\$\\{(. )\\}$");
Matcher matcher = PATTERN.matcher(placeholder);
boolean isMatch = matcher.find();
CodePudding user response:
From your example, I think you need to avoid greedy quantifier:
\$\{(. ?)\}
Notice the ?
after
which are reluctant quantifier: https://docs.oracle.com/javase/tutorial/essential/regex/quant.html
That should match ${var1}-txt-${var2}
Now, if you use ^
and $
as well, this will fail.
Note that you could also use StringSubstitutor from commons-text to perform a similar job (it will handle the parsing and you may use a Lookup
that capture the variable).
CodePudding user response:
Please, never say never guys:
^\$\{[^\}] \}[\}] $
it just matchs everything inside ${, and just accepts } closes at end, looks perfect fits!
${var}
-> Matches
${var-${anotherVar}}
-> Matches
${var} txt
-> Not Matches
${var}-txt-${var2}
-> Not Matches
even infinity nested will matches:
${var-${nestedVar-${deep1-${deep2}}}}
-> Matches