2016-04-04 14 views
-1

Der Code:PHP Regex - seltsam Problem mit mehreren Gruppen Capture

$pattern = '~(/(?P<lang>en|ru))?/foo(/(?P<bar>bar))?~'; 

preg_match($pattern, '/foo', $matches); 
var_dump($matches); 
/*output: 
array(1) { 
    [0] => 
    string(4) "/foo" 
}*/ 
preg_match($pattern, '/foo/bar', $matches); 
var_dump($matches); 
/*output: 
array(7) { 
    [0] => 
    string(8) "/foo/bar" 
    [1] => 
    string(0) "" 
    'lang' => 
    string(0) "" 
    [2] => 
    string(0) "" 
    [3] => 
    string(4) "/bar" 
    'bar' => 
    string(3) "bar" 
    [4] => 
    string(3) "bar" 
}*/ 

die Frage: Warum zum Teufel es <lang> in dem zweiten preg_match Anruf nicht erfassen und wie kann ich es beheben?

P.S. Ich habe diesen Regex auf https://www.regex101.com ausprobiert und dort fängt es richtig auf, aber auf meinem Rechner mit PHP7 tut es das nicht. Ich habe das Gefühl, dass regex101 die Ausgabe filtert.

+0

Keine Ahnung, was du meinst, aber vielleicht kann faules Zusammenpassen helfen: '(/ (? P en | ru)) ??/foo (/ (? P bar))?' –

+0

Ich meine, dass es nicht erfassen sollte 'lang' wenn es keine Übereinstimmung gibt. Es macht keinen Sinn. Und nein, ein weiteres '' 'hinzuzufügen, hat nicht geholfen. – jurchiks

+0

Bitte klären. Ich sehe in Ihrer Code-Demo, dass 'lang' leer ist:' 'lang' => string (0) "" '. Kein Text wurde erfasst. –

Antwort

1

Wie andere schon gesagt haben, funktioniert Regex einfach so. Soweit ich weiß, ist es ziemlich universell, Regexes zu verwenden. Es hat sogar Parallelen in der Programmierung im Allgemeinen, wie Java eine String zurückgebende Funktion benötigt, um eine String zurückzugeben (es sei denn, es wirft einen Fehler auf).

In PHP verwenden Sie array_filter auf $matches, um leere Einträge zu entfernen.

Auch ich schlage vor, mit Nicht-Erfassung (?:) Gruppen, die Unordnung zu schneiden:

(?:/(?P<lang>en|ru))?/foo(?:/(?P<bar>bar))?

Oder spaltete es in zwei regulären Ausdrücke: (?:/(?P<lang>en|ru)) und /foo(?:/(?P<bar>bar)).