1

I have the following text:

{{ some text {{ with nested text }} and again }} and some more text over here {{remove this too}}

I'd like to match the OUTERmost {{ }} brackets so that I'm left with:

and some more text over here

This is what I have so far:

var text = Regex.Replace(content, "{{[^}}]*}}",string.Empty);

Any ideas? Any help would be much appreciated.

UPDATE Adding in some links that might be helpful:

{{.+?}} http://www.regexr.com/3941i

{{.+}} http://www.regexr.com/3941f

RichC
  • 7,853
  • 19
  • 80
  • 137

3 Answers3

5
var text = Regex.Replace(content, "{{.+}}", string.Empty);

EDIT ( Balanced Matching )

string content = @"{{ some text {{ with nested text }} and again }} and some more text over here {{remove this too}}";

Regex re = new Regex(@" {{
    [^{}]*
    (
        (
            (?<Open>{{)
            [^{}]*
        )+
        (
            (?<Close-Open>}})
            [^{}]*
        )+
    )*
    (?(Open)(?!))
    }}", RegexOptions.IgnorePatternWhitespace);

var text = re.Replace(content, string.Empty);

For more details: http://blogs.msdn.com/b/bclteam/archive/2005/03/15/396452.aspx

EZI
  • 14,547
  • 2
  • 24
  • 31
  • That works but it seems to cheat a little - I'll change my example a little so you can see what I mean. – RichC Jul 06 '14 at 00:08
  • Is this a recursive regular expression? Yep. One booger of a regex. I didn't know C# could do that. – alvonellos Jul 06 '14 at 00:29
  • 1
    Under the `` line should it be this? `[^<>]*` or this? `[^{}]*` – RichC Jul 06 '14 at 19:34
  • great answer, but the "[^{}]*" is a little confusing since its not double {{}}. I am confused how would you solve for the example where the brackets {{ are replaced with non-identical characters 12 and }} are replaced with 34? Example string: 12TE12ST34ST34RING producing RING. Am I correct to try and use negative lookahead? – Danny Rancher Sep 21 '17 at 08:58
2

Your regex

{{[^}}]*}}

Does not work (try it), because the [^}}] will not allow it to go past the first* close curly. If you want to capture "all close curlys except the last two", then you need

\{\{.*\}\}[ ]+

Try it

I'm escaping the curlies to be safe. Although it works without them in regexstorm, they're special characters, and they should be escaped. I've also added the trailing space, to only capture the post-text, as you wish.

Note that this regex does not check that the curlies are balanced--it just blindly matches from the first two open curlies, to the last two. Regex is not suited to determining "balanced-ness".

(*The first, because the [^}}] is incorrect. The [^...] is a negative character class--it matches any one character that is not in the class (between the square brackets). So [^}}] is equivalent to [^}}}}}}}}}}}}}}}] is equivalent to [^}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}].)


Please consider bookmarking the Stack Overflow Regular Expressions FAQ for future reference.

Community
  • 1
  • 1
aliteralmind
  • 18,274
  • 16
  • 66
  • 102
  • I updated my initial text. I probably should have included the leading space for the resulting text since I don't want regex to look for that. So are you suggesting this is not a good jog for regex? what do you recommend? – RichC Jul 06 '14 at 00:23
  • I guess I should say *simple* regular expressions are not conducive to balancing. – aliteralmind Jul 06 '14 at 00:34
0

I don't think you can do it in one pass, this works in php, capture matched { } then trim off the outer brackets, repeat

(\{(?:[^\{\}]*+|(?0))*\})

other wise I would tokenize the string, break it into the {{, }} and text and process the results ( preg_match_all ) in php

(\{\{)|(\}\})|([^{}]+)

and process the results,

   Array
(
    [0] => Array
        (
            [0] => {{
            [1] =>  some text 
            [2] => {{
            [3] =>  with nested text 
            [4] => }}
            [5] =>  and again 
            [6] => }}
        )

    [1] => Array
        (
            [0] => {{
            [1] => 
            [2] => {{
            [3] => 
            [4] => 
            [5] => 
            [6] => 
        )

    [2] => Array
        (
            [0] => 
            [1] => 
            [2] => 
            [3] => 
            [4] => }}
            [5] => 
            [6] => }}
        )

    [3] => Array
        (
            [0] => 
            [1] =>  some text 
            [2] => 
            [3] =>  with nested text 
            [4] => 
            [5] =>  and again 
            [6] => 
        )

)

like if( item == {{ ) ++nesting; etc. if you follow the logic.

ArtisticPhoenix
  • 20,683
  • 2
  • 18
  • 34