Search code examples
phppcrepcregrep

Get inside of parent blocks in php regex


hello i have 2 parent (or more ...) block and many child blocks inside them.

Block1 {

    blockchild1 {

    }

    blockchild2 {

    }

    , ...
}

Block2 {

    blockchild1 {

    }

    blockchild2 {

    }

    , ...
}

i want to use php regex and get first all parents blocks inside

([a-z-0-9]*)\s*[{](.*?)[}]

but this regex stop when arrive to first childblock close } means first data receive is

Block1 {

    blockchild1 {

    }

but i want to get some thing like this

array 1 = Block1
array 2 = blockchild1 {

    }

    blockchild2 {

    }

    , ...

i want the regex pass child blocks [}] and get everything inside of parents block. my regex is PCRE (PHP)


Solution

  • You need to use a recursive pattern:

    $pattern = '~(\w+)\s*{([^{}]*(?:{(?2)}[^{}]*)*)}~';
    

    details:

    ~ # delimiter
    (\w+) # capture group 1: block name
    \s* # eventual whitespaces
    {
    (   # capture group 2
        [^{}]* # all that isn't a curly bracket
        (?:
            { (?2) } # reference to the capture group 2 subpattern
            [^{}]*
        )*
    )
    }
    ~
    

    Note that the reference to the capture group 2 is inside the capture group 2 itself, that's why the pattern is recursive.