2015-10-06 16 views
5

Ich will 'n' explodieren diese Zeichenfolge überprüfen:PHP preg_match_all, überprüfen und explodieren

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

zu:

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

ich folgende regexp gemacht:

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

, aber es ist zu hässlich und unterstützt nur bis zu fünf Parameter. Bitte helfen Sie mir einen rekursiven Teil zu machen, um alle Parameter zu extrahieren.

ps: Ja, ich diese zu var_name aufspalten, module_name und paramters Teile, dann kann ich Parameter Teil von '/' explodieren, aber ich mag es nicht.

Antwort

3

könnten Sie preg_split() verwenden.

Regex:

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

Und das erste und das dritte Element im Array verwerfen.

ideone Demo



EDIT: Um neue Bedingungen durch die OP in den Kommentaren angegeben beziehen sich (nicht in der Frage): Es sollte die Syntax ^\{\$\w+#\w+(?:/\w*)$ und tokenize in validieren var, Modul und Parameter unabhängig.

Regex:

~\G(?(?=^)\{\$(\w++)#(\w++)(?=[\w/]+}$))/\K\w*+~ 

Code:

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

$pattern = '@\G(?(?=^)\{\$(\w++)#(\w++)(?=[\w/]+}$))/\K\w*[email protected]'; 
$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); 
} 

Ausgang:

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

ideone Demo

+0

Richtig, aber ist es nicht validieren. –

+0

Bitte spezifizieren Sie, was genau in Ihrer Frage – Mariano

+0

validiert werden muss '{$ var_name # Modulname}' - dieses Format erforderlich. Argumente sind optional: '{$ var_name # Modulname/arg1/arg2 /.../ argN} 'Alle Namen und Werte (Var-Name, Modul-Name, Argumente) sind durch \ w + prüfbar. –

2
{\$([^#]+)#|\G(?!^)([^\/]+)\/|\G(?!^)(.*?)}$ 

Sie können einfach ein Spiel tun, statt und greifen die groups .Siehe Demo.

https://regex101.com/r/cJ6zQ3/18

$re = "/{\\$([^#]+)#|\\G(?!^)([^\\/]+)\\/|\\G(?!^)(.*?)}$/m"; 
$str = "{\$gallery#pager/collectionName/imageName/manual/no_effect/foo1/foo2/.../fooN}"; 

preg_match_all($re, $str, $matches); 
+0

1) super, thx. Ich werde '{\ $ ([^ #] +) # ([^ \ /] +) | \ G (?! ^) (\/[^ \ /] +)}' Verwenden, weil var_name ($ 1) und Modulname ($ 2) sind erforderlich. 2/a) Übereinstimmungen [3] indexiert von 1. Warum? 2/b) Was ist das \ G (?! ^)? Ich kann das nicht googeln. :( –