129 Stimmen

Wie lässt sich am effizientesten prüfen, ob ein PHP-String mit einem anderen String endet?

Der PHP-Standardweg, um zu testen, ob ein String $str endet mit einer Teilzeichenkette $test ist:

$endsWith = substr( $str, -strlen( $test ) ) == $test

Ist dies der schnellste Weg?

0 Stimmen

0 Stimmen

PHP 8.0 führt eine neue Methode für diese Aufgabe ein str_end_with : stackoverflow.com/a/64160081/7082164

3 Stimmen

153voto

mcrumley Punkte 5592

Was Assaf sagte, ist richtig. Es gibt eine eingebaute Funktion in PHP, die genau das tut.

substr_compare($str, $test, strlen($str)-strlen($test), strlen($test)) === 0;

Si $test ist länger als $str PHP wird eine Warnung ausgeben, also müssen Sie das zuerst überprüfen.

function endswith($string, $test) {
    $strlen = strlen($string);
    $testlen = strlen($test);
    if ($testlen > $strlen) return false;
    return substr_compare($string, $test, $strlen - $testlen, $testlen) === 0;
}

0 Stimmen

Sehr schön. Es scheint so, als ob ein In-Place-Vergleich schneller wäre als substr(), wie Assaf betont hat.

2 Stimmen

Die Antwort von mcrumley ist gut, aber sie sollte '===' statt '==' verwenden. '===' ist strenger und macht normalerweise das, was man will, während '==' zu bösen Überraschungen führen kann. mcrumleys dritter Codeschnipsel ist korrekt, aber die ersten beiden sind es nicht. substr_compare() gibt in einigen Fehlerfällen false zurück. In PHP ist false == 0, so dass die Codeschnipsel signalisieren würden, dass die Zeichenkette gefunden worden ist. Mit === passiert das nicht.

1 Stimmen

Ich bin heute auf einen Fehler gestoßen, der die von Ihnen angegebene Lösung ab PHP 5.5.11 nicht mehr unterstützt. bugs.php.net/fehler.php?id=67043

67voto

jscheel Punkte 2089

Diese Methode ist etwas speicheraufwendiger, aber schneller:

stripos(strrev($haystack), $reversed_needle) === 0;

Dies ist am besten, wenn Sie genau wissen, was die Nadel ist, so dass Sie die Umkehrung fest programmieren können. Wenn Sie die Nadel programmatisch umkehren, wird es langsamer als die frühere Methode.

2 Stimmen

-1 Ich bezweifle ernsthaft, dass dies schneller geht, und es ist knifflig (cool, aber normalerweise nicht hilfreich). Wenn der Heuhaufen nicht Ende mit der Nadel, stripos wird im schlimmsten Fall die gesamte Zeichenkette durchlaufen, während substr_compare wird höchstens die Länge der Nadel vergleichen. Ja, substr_compare erfordert die Berechnung der Länge des Heuhaufens (und der viel kleineren Nadel), aber diese Methode setzt voraus, dass y den Text vollständig zu kopieren und ihn möglicherweise in Kleinbuchstaben zu konvertieren.

0 Stimmen

Cooler Ansatz, aber (wie in der Antwort selbst erwähnt) in vielen Fällen ineffizient! Trotzdem ein "Upvote" dafür, dass es seltsam kreativ ist und zeigt, dass es immer mehr Wege geben kann, dasselbe zu tun, als man sich jemals vorstellen kann. Prost!

1 Stimmen

Ich habe diese Methode getestet und finde sie schneller als die akzeptierte Antwort. Selbst wenn Heuhaufen und Nadel im laufenden Betrieb vertauscht werden, ist sie schneller.

64voto

Oleksandr Yanovets Punkte 4631
$endsWith = substr_compare( $str, $test, -strlen( $test ) ) === 0

Negativer Versatz "beginnt vom Ende der Zeichenkette aus zu zählen".

3 Stimmen

IMO ist dies eine der besten der angebotenen Lösungen.

0 Stimmen

+200, wenn ich könnte. Die wichtigste Erkenntnis hier ist, dass die Verwendung einer negativen Länge den Endteil der Zeichenkette erhält. Sie könnten auch substr mit der Länge -ve verwenden und ein == gegen $test durchführen. Die anderen Antworten sind schlecht.

11voto

Patrick Smith Punkte 498

Hier ist eine einfache Möglichkeit zu prüfen, ob eine Zeichenkette mit einer anderen endet, indem man strpos ein Offset an der Stelle, an der die Zeichenkette gefunden werden soll:

function stringEndsWith($whole, $end)
{
    return (strpos($whole, $end, strlen($whole) - strlen($end)) !== false);
}

Unkompliziert, und ich denke, dass es in PHP 4 funktionieren wird.

8voto

Assaf Lavie Punkte 67504

Das hängt davon ab, welche Art von Effizienz Ihnen wichtig ist.

Ihre Version verbraucht aufgrund der zusätzlichen Kopie durch die Verwendung von substr mehr Speicher.

Eine alternative Version könnte die Originalzeichenkette nach dem letzten Vorkommen der Teilzeichenkette durchsuchen, ohne eine Kopie zu erstellen, wäre aber wahrscheinlich langsamer, da mehr Tests erforderlich wären.

Der effizienteste Weg ist wahrscheinlich, eine Schleife von Zeichen für Zeichen von der Position -sterlen(test) bis zum Ende der Zeichenkette zu machen und zu vergleichen. Das ist die minimale Menge an Vergleichen, die Sie hoffen können, zu tun, und es gibt kaum zusätzlichen Speicher verwendet.

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