Reputation: 473
Let's consider ${
the opening tag and }$
the closing tag. The opening tag should only occur at the start and the closing tag. The chars {
,}
,$
are allowed as long as they do not form one of the tags: So ${Macro{Inner}}$
is allowed.
This is what I tried: \$\{[^((\$\{)|(\}\$))]+\}\$
Upvotes: 1
Views: 203
Reputation: 13641
You have tried the pattern [^((\$\{)|(\}\$))]+
to prevent ${
or }$
being matched, but that is a misunderstanding of how character groups work.
[^((\$\{)|(\}\$))]
means match a single character that is not a (
, $
, {
, )
, |
, or }
.
The following working regex is an example of how to use a negative lookahead to avoid ${
or }$
being matched:
\$\{(?:(?!\$\{|\}\$).)*\}\$
If you want to match across newlines use RegexOptions.Singleline
.
(Although I have done so, it is not necessary to escape the {
and }
in the regex above because the regex engine can determine from the surrounding context that they should be interpreted as match the literal character.)
Upvotes: 1
Reputation: 74660
Don't need regex for this
s.StartsWith("${") && s.EndsWith("}$") && new[]{"${", "}$"}.All(x => x.IndexOf(x, 2, s.Length-4) == -1)
Why do I advocate not using a regex?
Upvotes: 1
Reputation: 163467
If the curly's don't have to be balances, you might use
(?<!\S)\${[^{}]*(?>(?:(?<!\$){|}(?!\$))[^{}]*)*}\$(?!\S)
The pattern matches:
(?<!\S)
Assert a whitespace boundary to the left\${
match ${
[^{}]*
Optionally repeat matching any char other than {
and }
(?>
Atomic group
(?:
Non capture group
(?<!\$){
Match {
asserting not {
to the left|
Or}(?!\$)
Match }
asserting not }
to the right)
Close non capture group[^{}]*
Optionally repeat matching any char other than {
and }
)*
Close the atomic group and optionally repeat}\$
Match }$
(?!\S)
Assert a whitespace boundary to the rightIf the parenthesis should be balanced, you could use:
(?<!\S)\${(?>(?<!\$){(?<c>)|[^{}]+|}(?!\$)(?<-c>))*(?(c)(?!))}\$(?!\S)
Upvotes: 1