4 Stimmen

Ist es besser, Look-behind oder Capture-Gruppen zu verwenden?

Ich bin mir nicht sicher, ob das eine "besser" ist als das andere, und warum das so sein sollte, aber ich habe eine Originalsaite, die so aussieht:

$string = '/random_length_user/file.php';

Nun gibt es zwei Möglichkeiten, es abzugleichen, die erste mit Hilfe meines neuen Freundes, dem Rückblick, und die zweite ohne:

preg_match("%(?<=^/)([^/]*)%", $string, $capture);
preg_match("%^/([^/]*)%", $string, $capture);

Sie kehren der Reihe nach zurück:

Array
(
    [0] => random_length_user
)
Array
(
    [0] => /random_length_user
    [1] => random_length_user
)

Im Wesentlichen erhalte ich das gewünschte Ergebnis in $capture[0] mit look-behind und in $capture[1] ohne. Die Frage ist nun ... gibt es einen Grund, eine dieser Methoden der anderen vorzuziehen?

3voto

K Prime Punkte 5719

Es macht wahrscheinlich keinen Unterschied bei preg_match aber es ist wichtig, wenn Sie preg_replace da sie sich darauf auswirkt, was ersetzt werden soll.

Es könnte auch ein Problem sein, wenn Sie einen globalen Abgleich durchführen, da die erfassende Gruppe Zeichen verbraucht, während die Umleitungen nicht verbraucht werden

Ein triviales Beispiel:

  • /(?<=a)a/g con 'aaaa' gibt Array('a', 'a', 'a')
  • /(a)a/g con 'aaaa' gibt Array('aa', 'aa')

1voto

Alan Moore Punkte 70949

Das Problem ist, dass der Look-Behind-Ansatz nicht so flexibel ist; er scheitert, wenn man mit Übereinstimmungen variabler Länge zu tun hat. Nehmen wir zum Beispiel an, Sie wollten den Dateinamen in Ihrem Beispiel extrahieren und wüssten den Namen des Verzeichnisses nicht. Die Capture-Group-Technik funktioniert immer noch gut:

preg_match("%^/\w+/([^/]*)%", '/random_length_user/file.php');

Array
(
    [0] => /random_length_user/file.php
    [1] => file.php
)

...aber der Lookbehind-Ansatz nicht, weil Lookbehind-Ausdrücke nur mit einer festen Anzahl von Zeichen übereinstimmen können. Es gibt jedoch eine noch bessere Alternative: \K den Operator MATCH POINT RESET. Wo auch immer Sie ihn einsetzen, die Regex-Engine tut so, als ob die Übereinstimmung wirklich dort begonnen hätte. So erhalten Sie das gleiche Ergebnis wie mit einem Lookbehind, ohne die Beschränkung der festen Länge:

preg_match('%^/\w+/\K[^/]+$%', '/random_length_user/file.php');

Array
(
    [0] => file.php
)

Soweit ich weiß, ist diese Funktion nur in Perl 5.10+ und in Tools (wie PHPs preg_ Funktionen), die von der PCRE-Bibliothek unterstützt werden. Die PCRE-Referenz finden Sie unter die Manpage und suchen (F3) nach \K .

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X