Aley
Aley

Reputation: 8640

How to match variables starting with $ with regex?

The case is the following:

I have this string variations:

['var1' => $var1, 'var2' => $obj->var1['asd']]
[ 'var1' => $var1, 'var2' => $obj->var1 ]
['var1' => $var1, 'var2' => $var2]

I need to match $var, $obj->var1['asd'] and $obj->var1.

I came that far:

(\$[^,\s\]]+]?)

It almost works, but still the last case doesn't. See it in action here: regex101.com/r/cI0yP0/3

UPDATE:

Thanks for all your answers. They all work perfectly fine.

Now as Joe pointed out, there might be other cases such as the following.

['var' => $obj->var1->var2[2]->var3['test']->var4]
['var1' => $obj->var1[$obj2->var1['one']]]
['var2' => $obj[3]['var']]
['var3' => $obj->method()]

Upvotes: 4

Views: 92

Answers (5)

Joe
Joe

Reputation: 57169

This will allow you to capture any number of variables chained together and won't include the trailing square bracket:

 \$(?:(?:(?<!\$)->)?(?:[a-zA-Z]\w*(?:\[[^\[\]]+\])*)(?:\(\))?)+

This will capture $obj->var1->var2[2]->method1()->var3['test']['test2']->method2() for example.

Demo

This does not support nested brackets. i.e. $obj->var1[$obj2->var1['one']] To balance brackets you would need to use a proper parser

Upvotes: 2

Federico Piazza
Federico Piazza

Reputation: 30995

You brought a nice regex exercise. Below you can find 3 different regex to solve your problem.

Alternation with multiple groups

Not sure if you may like using a regex like this:

(\$.*?),|(\$.*?\])\]|(\$.*?)\]

Working demo

Regular expression visualization


Single group with alternation

However, have improved above regex and can come up with this:

(\$.*?\]?)(?:,|\])

Regular expression visualization

Working demo


Single group with character class

And adding a character class for better performance. I think this is the best.

(\$.*?\]?)[,\]]

Regular expression visualization

Working demo

Upvotes: 3

Saleem
Saleem

Reputation: 8978

Try following regex:

\$.+?(?=,|\s|\])(?:\](?=\]))?

See DEMO

Based on your sample input, it will capture:

$var1
$obj->var1['asd']
$var1
$obj->var1
$var1
$var2

Upvotes: 0

anubhava
anubhava

Reputation: 785098

You can use this regex with an optional match in the end for [...] part:

\$[^][,\s]+(?:\[[^]]*\])?

RegEx Demo

Upvotes: 0

Pedro Lobito
Pedro Lobito

Reputation: 98901

(\$[\w]+(?:->[\w]+)?(?:\[.*?\])?)

DEMO

https://regex101.com/r/cI0yP0/6

Upvotes: 1

Related Questions