It's a bit hard to explain what I really want (better title suggestions are appreciated so people can find this easily in the future).
Suppose I have this:
{
{
$myTagThing$
}
}
I want to match
{
$myTagThing$
}
ie match everything from the last {
before $myTagThing$
until the first }
after $myTagThing$
.
So I thought I'd need this \\{.*\\$myTagThing\\$.*\\}
, but it will also match the first {
and last }
in the string (ie the whole example). Then I tried using a lookahead and a lookbehind (both negative) \\{(.*(?!\\{))\\$myTagThing\\$.*(?<!\\})\\}
( https://regex101.com/r/RfdHUH/1/ ). But this still doesn't work.
My theory is that I might be using lookahead and lookbehind the wrong way since this is the first time I use them.
Any ideas?
EDIT: flags are \\gms
.
NOTE This was upvoted 3 times and marked as the accepted answer for revision 2 of this question, before the question was changed to a different scenario, and this answer was unaccepted.
You need to look for: opening-curly-brace, then a sequence of characters which are not open or close-curly-brace, then close-curly-brace.
Specifically: {[^{}]*}
EDIT: This addresses a { $myTagThing$ {} }
scenario no longer included in question.
Regarding your updated question. What you want, in .NET, is called balanced groups
. In other regex engines, balanced constructs/expressions
. The terminology slightly varies, the syntax is wildly different between engines, and so is the behavior.
Anyway, to capture the largest {}
contents possible, you want:
[^{}]*
(
((?'Open'{)[^{}]*)+
((?'Close-Open'})[^{}]*)+
)*
(?(Open)(?!))
(Set the ignore whitespace flag or collapse this regex). This is the core of your answer. We just modify it with the first and last line here:
\{[^{}]*myTagThing
[^{}]*
(
((?'Open'{)[^{}]*)+
((?'Close-Open'})[^{}]*)+
)*
(?(Open)(?!))
[^{}]*\}
The "one regex" solution can get complicated fast, but if you find yourself using .NET regexes often, you might find the following worth looking into:
Searching for specific text inside balanced chars (recursive
The link above is where I had an issue where I was looking for a string like:
Type VAR.*while{{VAR++}}
where the while
could be followed by balanced {}
. The bounty-awarded answer is the one you want to look at. It's a more complicated problem than yours, but you can see that it gets insane pretty quick:
Also see the official documentation on this feature:
Another way, modifying the OP's original approach:
\{{1}\s*\$myTagThing\$.*?\}
The {1}
indicates matching the previous character exactly once. The \\s*
captures white space. The .*?
makes the search for the right brace non-greedy.
Of course if the thing is multiline you need to enable that as well.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.