0

String to parse:

$str = "
public   $xxxx123;
private  $_priv   ;
         $xxx     = 'test';
private  $arr_123 = array();
"; //    |       |
   //     ^^^^^^^---- get the variable name

What I got so far:

    $str = preg_match_all('/\$\S+(;|[[:space:]])/', $str, $matches);
    foreach ($matches[0] as $match) {
        $match = str_replace('$', '', $match);
        $match = str_replace(';', '', $match);
     }

It works but I want to know if I can improve the preg, e.g. get rid of the two str_replace and maybe include \t in (;|[[:space:]])

0

3 Answers 3

4

Using a positive lookbehind, you can get only that what you need, to be sure you'll only match valid variable names, I've used this:

preg_match_all('/(?<=\$)[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/',$str,$matches);
var_dump($matches);

which correctly shows:

array (
  0 => 
  array (
    0 => 'xxxx123',
    1 => '_priv',
    2 => 'xxx',
    3 => 'arr_123'
  )
)

Which is all you need, no memory waisted on an array containing all variables with their leading and/or trailing chars.

The expression:

  • (?<=\$) is a positive lookbehind
  • [a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*: is the regex PHP's site suggests themselves on their document pages
Sign up to request clarification or add additional context in comments.

6 Comments

this would also match other random strings like $("=§/&="§/$. also it would not properly match something like $x=123;
still would match for example in here "!"§$%&/()=?`" -> $%&/()
@andreasLinden: I've edited my answer, to now use the regex PHP recommend themselves to match only valid variable names
okay fine, what is missing now to have a perfect solution: exclude variables inside of single quoted strings :D
@AndreasLinden: That'll be a bit tricky, since lookarounds have to be of fixed lengths, but then again, you could just preg_replace('/(?<=\')(.*)\$/', '$1', $str); to remove all $ from single quoted strings
|
1

simply use backreferences

preg_match_all('/\$(\S+?)[;\s=]/', $str, $matches);
foreach ($matches[1] as $match) {

     // $match is now only the name of the variable without $ and ;
}

Comments

1

I changed the regex a little bit, take a look:

$str = '
public   $xxxx123;
private  $_priv   ;
         $xxx     = "test";
private  $arr_123 = array();
';

$matches = array();

//$str = preg_match_all('/\$(\S+)[; ]/', $str, $matches);
$str = preg_match_all('/\$(\S+?)(?:[=;]|\s+)/', $str, $matches); //credits for mr. @booobs for this regex

print_r($matches);

The output:

Array
(
    [0] => Array
        (
            [0] => $xxxx123;
            [1] => $_priv 
            [2] => $xxx 
            [3] => $arr_123 
        )

    [1] => Array
        (
            [0] => xxxx123
            [1] => _priv
            [2] => xxx
            [3] => arr_123
        )

)

Now you can use the $matches[1] in the foreach loop.

::Update::

After using regex "/\$([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)/" the output looks correct.

String:

$str = '
public   $xxxx123; $input1;$input3
private  $_priv   ;
         $xxx     = "test";
private  $arr_123 = array();

';

And the output:

Array
(
    [0] => Array
        (
            [0] => $xxxx123
            [1] => $input1
            [2] => $input3
            [3] => $_priv
            [4] => $xxx
            [5] => $arr_123
        )

    [1] => Array
        (
            [0] => xxxx123
            [1] => input1
            [2] => input3
            [3] => _priv
            [4] => xxx
            [5] => arr_123
        )

)

5 Comments

I'd change the regex even more so that it matches even if there's no space before assignation operator: \$(\S+?)(?:[=;]|\s+)
problem here: $input; $input2; it does not match $input2;
@sbooob Nice one, I'll change the regex.
@DanFromGermany I don't have that problem? What string are you using?
This simple one seems to work: /\$([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)/. "Simple" as it is just the regex for a valid PHP var name according to PHP manual

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.