user3052560
user3052560

Reputation: 177

Match everything between parenthesis

I currently have this regex

/^(@if([a-zA-z0-9.=(\s*)]+))/

I'm looking to match any string along the lines of @if (expression), which includes strings like:

@if (name == false)
@if (1 == 1)
@if ((name == false) && 1 == 1)
@if (model.name)
@if (model|length > 5)

Yet the regex I have right now also accepts these strings:

@if (1 == 1)s

How would I fix it?

Upvotes: 1

Views: 58

Answers (2)

anubhava
anubhava

Reputation: 785058

Since you're dealing with nested brackets here you will need to use recursive regex feature of PCRE regex.

$s = '@if ((name == false) && 1 == 1)';
if (preg_match('/(@if) \s* ( \( (?: [^()]* | (?2) )* \) ) \s*$ /x', $s, $arr))
   print_r($arr);

OUTPUT

Array
(
    [0] => @if ((name == false) && 1 == 1)
    [1] => @if
    [2] => ((name == false) && 1 == 1)
)

PS: Due to sue \s*$ in the end it won't match @if ((name == false) && 1 == 1)foo

Upvotes: 1

mrks
mrks

Reputation: 8333

Unfortunately, the other answer was deleted. It gave ^@if\s?\(.*\)$ as a regexp, which would solve your problem with other characters at the end.

However, I would suggest for you to rethink your approach. You are experiencing an inherent limitation of Regular Expressions. You cannot count the number of open vs. closed brackets. Thus, any regexp would also validate @if ())). This question has more details.

There are some extensions to regular expressions that allow for recursion, but I would avoid using that. Regexps are just not the right tool here.

Upvotes: 0

Related Questions