Kevin Castejon
Kevin Castejon

Reputation: 122

REGEX good start but need some excluding

I have that regex

\{([^{}]|(?R))*\}

that matches fine the outermost brackets content

foo{
    subfoo{
       "foofoofoo..."
    }
}foo

//Matches :
//   {
//   subfoo{
//      "foofoofoo..."
//   } 
//}

But I need to add some exclusion to that:

So the following text should give:

foo{
   subfoo{
      "foofoofoo... { "
   }
}foo

//Matches :
//   {
//   subfoo{
//      "foofoofoo... { "
//   } 
//}

and

foo{foofoofoo} ;

//Matches nothing

Can anyone help?

Upvotes: 0

Views: 39

Answers (1)

Casimir et Hippolyte
Casimir et Hippolyte

Reputation: 89565

First, change your pattern to its unrolled version (that is more efficient):

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

Then, following the same idea, you can easily describe parts into quotes:

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

(same thing to include single quotes too, exclude the single quote from the negated character classes and add a branch that describes the quoted part)

You can also take escaped quotes in account:

\{[^{}"]*+(?:"[^"\\]*+(?s:\\.[^"\\]*)*+"[^{}"]*|(?R)[^{}"]*)*+\}

If you don't want closing curly brackets to be followed by a ; add a negative lookahead as suggested. (?!\s+;) or (?!\s*;) depending of what you want. But if you only want to target the outermost closing bracket, you have to check if you are in a recursion or not before, using a conditional statement (?(condition)then|else) : (?(R)|(?!\s+;)) or (?(R)|(?!\s*;))

Upvotes: 1

Related Questions