2013-03-16 13 views
67

Ich bin schrecklich mit regulären Ausdrücken. Ich versuche, diese zu ersetzen:Ersetzen Sie preg_replace() e Modifikator mit preg_replace_callback

public static function camelize($word) { 
    return preg_replace('/(^|_)([a-z])/e', 'strtoupper("\\2")', $word); 
} 

mit preg_replace_callback mit einer anonymen Funktion. Ich verstehe nicht, was der \\ 2 tut. Oder genau wie preg_replace_callback funktioniert.

Was wäre der richtige Code, um dies zu erreichen?

+1

Der ** e ** Modifikator [veraltet] (http://php.net/manual/en/reference.pcre.pattern.modifiers.php) ab PHP 5.5.0 – HamZa

+8

@HamZaDzCyberDeV Ich weiß, . Das ist einer der Gründe, warum ich es durch preg_replace_callback ersetzen möchte. – Casey

+2

Es gibt eine manuelle Seite für ['preg_replace_callback'] (http://php.net/preg_replace_callback). Und "\\ 2" wird in diesem Rückruf zu "$ Übereinstimmungen [2]". Oder um welchen Teil handelt es sich konkret? – mario

Antwort

59

In einem regulären Ausdruck können Sie Teile der übereinstimmenden Zeichenfolge mit (brackets); In diesem Fall erfassen Sie die Teile (^|_) und ([a-z]) des Spiels. Diese sind beginnend bei 1 nummeriert. Sie haben also die Rückverweise 1 und 2. Match 0 ist die gesamte übereinstimmende Zeichenfolge.

Der /e Modifikator nimmt ein Ersatz-String und ersetzt Backslash gefolgt von einer Zahl (zB \1) mit dem entsprechenden Rückverweis -, sondern weil Sie in einem String sind, dann müssen Sie den umgekehrten Schrägstrich entkommen, so dass Sie '\\1' bekommen . Es führt dann (effektiv) eval aus, um die resultierende Zeichenfolge als PHP-Code auszuführen (weshalb es veraltet ist, weil es eval auf unsichere Weise verwendet).

Die Funktion preg_replace_callback übernimmt stattdessen eine Callback-Funktion und übergibt ihr ein Array mit den übereinstimmenden Rückverweisen. Wo Sie also '\\1' geschrieben hätten, greifen Sie stattdessen auf Element 1 dieses Parameters zu - z. Wenn Sie eine anonyme Funktion des Formulars function($matches) { ... } haben, ist die erste Rückreferenz innerhalb dieser Funktion $matches[1].

So ein /e Argument von

'do_stuff(\\1) . "and" . do_stuff(\\2)' 

könnte ein Rückruf von

werden
function($m) { return do_stuff($m[1]) . "and" . do_stuff($m[2]); } 

Oder in Ihrem Fall

'strtoupper("\\2")' 

werden könnte

function($m) { return strtoupper($m[2]); } 

Beachten Sie, dass $m und $matches keine magischen Namen sind, sie sind nur der Parametername, den ich bei der Deklaration meiner Callback-Funktionen angegeben habe. Außerdem müssen Sie keine anonyme Funktion übergeben, es könnte ein Funktionsname als Zeichenfolge oder etwas in der Form array($object, $method), as with any callback in PHP, z.

function stuffy_callback($things) { 
    return do_stuff($things[1]) . "and" . do_stuff($things[2]); 
} 
$foo = preg_replace_callback('/([a-z]+) and ([a-z]+)/', 'stuffy_callback', 'fish and chips'); 

Wie bei jeder Funktion können Sie auf Variablen außerhalb Ihres Rückrufs (aus dem umgebenden Bereich) standardmäßig nicht zugreifen. Wenn Sie eine anonyme Funktion verwenden, können Sie das Schlüsselwort use verwenden, um die Variablen zu importieren, auf die Sie zugreifen müssen, as discussed in the PHP manual. z.B.wenn das alte Argument

war
'do_stuff(\\1, $foo)' 

dann der neue Rückruf aussehen könnte

function($m) use ($foo) { return do_stuff($m[1], $foo); } 

Gotchas

  • Verwendung von preg_replace_callback ist statt der /e Modifikator auf dem regulären Ausdruck, so dass Sie Sie müssen dieses Flag aus Ihrem "Muster" -Argument entfernen. So würde ein Muster wie /blah(.*)blah/mei/blah(.*)blah/mi werden.
  • Der Modifikator /e verwendet eine Variante von addslashes() intern auf den Argumenten, so dass einige Ersetzungen verwendet stripslashes(), um es zu entfernen; In den meisten Fällen möchten Sie wahrscheinlich den Anruf von Ihrem neuen Rückruf zu stripslashes entfernen.
Verwandte Themen