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
