Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP preg_match_all, check & explode

I want to check 'n' explode this string:

{$gallery#pager/collectionName/imageName/manual/no_effect/foo1/foo2/.../fooN}

to:

var_name[0] => 'gallery',
modul_name[0] => 'pager',
3[0] => 'collectionName',
4[0] => 'imageName',
5[0] => 'manual'
...
N[0] => 'fooN'

I made the following regexp:

/{\$(?P<var_name>[^#]+)#(?P<module_name>[^\/]+)(?:\/(\w+)(?:\/(\w+)(?:\/(\w+)(?:\/(\w+)(?:\/(\w+))?)?)?)?)?}/

, but it's too ugly and only support up to five parameters. Please help me to make a recursive part to extract all parameters.

ps: Yes, i can split this to var_name, module_name and paramters parts, then i can explode parameters part by '/', but i don't like it.

like image 230
Varteresz Gabor Avatar asked Oct 06 '15 12:10

Varteresz Gabor


People also ask

What is Preg_match_all in PHP?

PHP preg_match_all() Function The preg_match_all() function returns the number of matches of a pattern that were found in a string and populates a variable with the matches that were found.

What is pattern matching in PHP?

preg_match() in PHP – this function is used to perform pattern matching in PHP on a string. It returns true if a match is found and false if a match is not found. preg_split() in PHP – this function is used to perform a pattern match on a string and then split the results into a numeric array.

What does preg match return?

preg_match() returns 1 if the pattern matches given subject , 0 if it does not, or false on failure. This function may return Boolean false , but may also return a non-Boolean value which evaluates to false .


1 Answers

You could use preg_split().

Regex:

preg_split('@([$#])|[{}/]+@', $text)

And discard the first and third item in the array.

ideone Demo



EDIT: To reflect new conditions specified by the OP in comments (not in the question): It should validate the syntax ^\{\$\w+#\w+(?:/\w*)$ and tokenize in var, module and parameters independently.

Regex:

~\G(?(?=^)\{\$(\w++)#(\w++)(?=[\w/]+}$))/\K\w*+~
  • \G Matches at the beggining of string or at the end of last match.
  • (?(?=^) ... ) If at start of string
  • \{\$(\w++)#(\w++)(?=[\w/]+}$ Capture var and module, and validate syntax until the end of string.
  • /\K Match 1 slash and reset matched text.
  • \w*+ Match 1 parameter.

Code:

// http://stackoverflow.com/q/32969465/5290909

$pattern = '@\G(?(?=^)\{\$(\w++)#(\w++)(?=[\w/]+}$))/\K\w*+@';
$text = '{$gallery#pager/collectionName/imageName/manual/no_effect/foo1/foo2/fooN}';

$result = preg_match_all($pattern, $text, $matches);

if ($result === 0) {
    // is invalid, does not match '~^\{\$\w+#\w+(?:/\w*)+$~'
    echo "Invalid text";
} else {
    // Assign vars (only to clarify)
    $module_name = array_pop($matches)[0];
    $var_name = array_pop($matches)[0];
    $parameters = $matches;

    echo "VAR NAME: \t'$var_name'\nMODULE:  \t'$module_name'\nPARAMETERS:\n";
    print_r($matches);
}

Output:

VAR NAME:   'gallery'
MODULE:     'pager'
PARAMETERS:
Array
(
    [0] => collectionName
    [1] => imageName
    [2] => manual
    [3] => no_effect
    [4] => foo1
    [5] => foo2
    [6] => fooN
)

ideone Demo

like image 167
Mariano Avatar answered Oct 23 '22 03:10

Mariano