Reputation: 122
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
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