Tell RegEx to ignore parentheses when inside a quote

I have the following RegEx that is used and working:

/\ B@ (@?\w+(?:::\w+)?)([ \t]*)(\( ( (?>[^()]+) | (?3) )* \))?/x

If this line @extends('template', 'test') correctly groups and gives me what I need.

The problem is that the string contains a closed bracket inside quotation marks - it will not be executed:

@extends('template', 'te)st') gives @extends('template', 'te) as the output

How can I tell this RegEx to ignore the brackets that are inside the quotation marks (either ' or " )

Here is the RegExr trial demo: http://regexr.com/v1?396ci

And here is a list of lines that everyone should go through:

 @extends('template', 'test') // working @extends('template', $test) // working @extends('template', 'te()st') // working @extends('template', 'te)st') // broken @extends('template', 'te())st') // broken @extends('template', 'te(st') // broken @extends('template', 'test)') // broken @extends('template', '(test') // broken 

I narrowed it down - and I think I need to say

 ( \( <-- only if not inside quotes ( (?>[^()]+) | (?3) )* \) <-- only if not inside quotes )? 

But I can't figure out how to apply this rule to these specific brackets.

+5
source share
1 answer

You can use lookahead for this purpose.

Here is my regex that will match the second argument of all extends

(= (\ W +) |? \ + ()) [\ ) (] +

Structure:

' : start searching for a line with a quote

?=XXX) : A positive look ahead that ensures XXX is in front

(\w+\)|\w+\() : find either opening or closing curly braces

Now, if this view were successful, we can be sure that we have a quote followed by a bracket. Now we can just write a regular expression to create parentheses

[\w\)\(]+ : Doing just that

Now that we can find quotes with parentheses inside it, we can use the if-else condition to use the appropriate rules for each case

(?(?=regex)then|else)

Here's how I implemented it:

 (?(?='(?=(\w+\)|\w+\())) <- condition, same as above '[\w\)\(]+' <- We have a match so we ignore parenthesis |'\w+' <- Here we don't ) 

ps. I did not understand much of what you wrote for another part of your regular expression, perhaps to cover some other cases, so I am not writing to change the original regular expression. You can simply switch the check to the second parameter with the above

Here is my regex that matches all your cases.

\ B@ \w+\('[\w+\s]+',\s+(?(?='(?=(\w+\)|\w+\()))'[\w\)\(]+'|('\w+'|\$\w+))\)

You can see the test cases here.

PS. To show that this really works, I added some unsuccessful test cases.

+3
source

All Articles