Regex: match all single or double quoted strings inside parenthesis which may or may not contain nested parenthesis

I'm trying to figure out how I can match all single or double quoted strings inside of parenthesis. The problem is that the parenthesis may contain child parenthesis.

Here is an example of the content I'm trying to obtain matches in:

$v->label('Name')->for('name'),
$v->input()->id('name')->wireModelDefer('name')
    ->class(($this->error('name') ? 'border-red-500' : 'border-gray-300') . ' rounded-lg w-full'),
$v->if($this->error('name'), fn () => $v->p($this->error('name'))->class('text-xs text-red-600'))

Now, I want to match all single or double quoted strings inside of the class() method.

So if you look at the above example, here is the context of what I need to match:

->class(($this->error('name') ? 'border-red-500' : 'border-gray-300') . ' rounded-lg w-full')
->class('text-xs text-red-600')

Now, given these 2 examples, as you can see, they are PHP methods which contain Tailwind class names. I want to use regex to match the Tailwind class names within this class() method call. If you're wondering why, it is for use with a VSCode extension so I can get Tailwind autocomplete inside my PHP code.

So anyways, given the above 2 lines, what should be extracted are the following:

border-red-500 border-gray-300 rounded-lg w-full
text-xs text-red-600

If name also happens to be matched, then so be it. I don't really care about that. Just as long as the single or double quoted strings inside the class() method get matched.

As for regex I've tried, here are a few examples:

class\([\"']([^\"']*)[\"']\)

Which matched:

text-xs text-red-600

This works great if there are no child parenthesis inside of the class() method arguments.

So, I tried some different things:

class\((.*?)\)

This unfortunately only captured:

($this->error('name'

Then I started trying some more advanced stuff, like the recursion operator:

class\(([^()]|(?R))*\)

This only matched:

'

Trying different child parenthesis matches:

class\('[^']*'(?=[^(']*('[^']*'[^'(]*)*\))\)

Only matches:

class('text-xs text-red-600')

Trying to get more complex:

class\((?<=\()(?:'[^']*'|[,\s]+|\d+)+(?=\))\)

Still, I only get the simpler match.

Is this possible with regex? I just want to obtain all of the single or double quoted strings inside of the class() method, even if it has nested parenthesis.

Edit:

I feel I am getting closer with this:

class\((?<=\().*(?=\))\)

Which matched:

class(($this->error('name') ? 'border-red-500' : 'border-gray-300') . ' rounded-lg w-full')
class('text-xs text-red-600'))

However, I still need to have it match the quoted strings inside, not the entire thing.



Read more here: https://stackoverflow.com/questions/66342334/regex-match-all-single-or-double-quoted-strings-inside-parenthesis-which-may-or

Content Attribution

This content was originally published by kjdion84 at Recent Questions - Stack Overflow, and is syndicated here via their RSS feed. You can read the original post over there.

%d bloggers like this: