boop
boop

Reputation: 7788

Everything but pattern

I want to capture everything between 2pairs of curly brackets {{ ... }}.

What I already have is this

/{{([^{}]+)}}/i
here with some spaces, for better reading:
/  {{  [^{}]+  }}  /i 

But this obviously won't let me do something like {{ function(){ echo 1234; }; }}

So my question is: How can I exclude patterns instead of lists?

Upvotes: 1

Views: 32

Answers (2)

Casimir et Hippolyte
Casimir et Hippolyte

Reputation: 89547

You need to build a recursive subpattern that will match balanced curly brackets.

({[^{}]*+(?:(?1)[^{}]*)*})

So to integrate this to your whole pattern:

{({([^{}]*+(?:(?1)[^{}]*)*+)})}

now the content you are looking for is in the capture group 2

subpattern details:

(               # open the capture group 1
    {           # literal {
    [^{}]*+     # all that is not a curly bracket (possessive quantifier)
    (?:         # non capturing group
        (?1)    # recursion: `(?1)` stands for the subpattern
                # inside the capture group 1 (so the current subpattern)
        [^{}]*  #
    )*+         # repeat as needed the non capturing group
    }           # literal }
)               # close the capture group 1

The possessive quantifiers are used here to prevent to much backtracking if brackets are not well balanced.

The advantage of this way is that it works whatever the level of nested brackets, see the example:

demo

Upvotes: 0

chris85
chris85

Reputation: 23892

Here's the regex.

\{{2}(.*?)\}{2}

The \ is escaping the first curly because you want to find the actual character. The next open and closing curly tell it how many of the previous character to find. The period means any character. That paired with the asterisk and question mark mean find everything until the next 2 curly braces (2 because of the {2} again). Questions?

Upvotes: 2

Related Questions