I am trying to wrap my head around a bug I am finding with the .Net balancing groups regex.
I am trying to match !{}
as an opening/closing combination.
Current Regex -> !{[^!{}]*(((?<Open>!{)[^!{}]*)+((?<Close-Open>})[^!{}]*)+)*(?(Open)(?!))}
this matches !{some random stuff here}
successfully. It also matches !{some other Stuff !{} with nesting}
However, it DOES NOT match this !{some stuff with {} just curly braces}
at all. It seems the '{}' inside the string is causing some issues as it seems to think that the group is no longer "balanced"
I am testing all of this on http://regexstorm.net/tester which is a great place for .Net specific regex testing.
To be fair I am no regex expert, and have unashamedly copied / manipulated the regex from this site http://www.regular-expressions.info/balancing.html
I don't need it to be able to match nesting as I will use c# to traverse recursively into the matches, but i just need to be able to get a positive match on the example that is failing above.
UPDATE
Here is what the initial goal of the pattern is. Much like with Razor pages where it matches @{ some C# code here } as code blocks, I have used a pattern of !{some code here} to demarcate sections of code inside a html page. I have written a website for a client where they use those "replacers" to execute custom logic inside their html pages. so for example :
<p> Hello !{CurrentSession.GetUser().FirstName}</p>
When the page is rendered out I use Regex to identify those "replacers" and then use Springframework.Net to execute that code against a known context.
This has all worked brilliantly since 2009 ( yes over 10 years ago ! ) but now they are starting to use a lot more Json type data and that is where I discovered this bug / issue with my regex.
So Imagine this example
<script type="text/javascript">
var myArray = [ !{CurrentSession.GetUser().GetDataOrDefault( '{Name:"MyName"}' )} ];
</script>
As you can see with the above example, there is Json with curly braces '{}' inside the replacer I'm trying to match !{} and that is where the regex is failing.
PS the '!' is NOT optional it MUST open with '!{' and close with '}'
thanks in advance
You may use
!{(?>[^{}]+|(?<Open>{)|(?<Close-Open>}))*}
The regex will find an exclamation mark, and then a {
followed with any amount of paired nested curly braces up to the matching close brace.
See the regex demo.
Details
!{
- a !{
substring(?>[^{}]+|(?<Open>{)|(?<Close-Open>}))*
- zero or more repetitions (allowing no backtracking into the alternation atomic group) of
[^{}]+|
- 1+ chars other than {
and }
, or(?<Open>{)|
- a {
char pushed on to Group "Open" stack(?<Close-Open>})
- a }
char popped from Group "Open" stack saving the substring matched in Group "Close"}
- a }
char.