Wie kann ich zwei Funktionen schreiben, die eine Zeichenfolge annehmen und zurückgeben, wenn sie mit dem angegebenen Zeichen / der angegebenen Zeichenfolge beginnt oder damit endet?
Zum Beispiel:
$str = '|apples}';
echo startsWith($str, '|'); //Returns true
echo endsWith($str, '}'); //Returns true
s($str)->startsWith('|')
unds($str)->endsWith('}')
hilfreich, wie in dieser eigenständigen Bibliothek gefunden .Antworten:
Verwenden Sie diese Option, wenn Sie keinen regulären Ausdruck verwenden möchten.
quelle
$length
wird in der letzten Zeile der nicht benötigtendsWith()
.return substr($haystack, -strlen($needle))===$needle;
if
insgesamt vermeiden, indem Sie$length
als dritten Parameter Folgendes übergebensubstr
:return (substr($haystack, -$length, $length);
. Dies behandelt den Fall,$length == 0
indem eine leere Zeichenfolge und nicht die gesamte zurückgegeben wird$haystack
.Mit der
substr_compare
Funktion können Sie Anfang und Ende überprüfen mit:Dies sollte eine der schnellsten Lösungen für PHP 7 ( Benchmark-Skript ) sein. Getestet gegen 8KB Heuhaufen, Nadeln unterschiedlicher Länge und volle, teilweise und keine Streichhölzer.
strncmp
ist für Anfänge eine Berührung schneller, kann aber die Enden nicht überprüfen.quelle
strrpos
was sofort fehlschlagen sollte, wenn die Nadel nicht zum Beginn des Heuhaufens passt.-strlength($haystack)
) und von dort aus rückwärts suchen ? Bedeutet das nicht, dass Sie nichts suchen? Ich verstehe auch die!== false
Teile davon nicht. Ich vermute, dies beruht auf einer Eigenart von PHP, bei der einige Werte "wahr" und andere "falsch" sind, aber wie funktioniert das in diesem Fall?xxxyyy
Nadel =yyy
undstrrpos
die Suche beginnt von der erstenx
. Jetzt haben wir hier keine erfolgreiche Übereinstimmung (x statt y gefunden) und wir können nicht mehr rückwärts gehen (wir stehen am Anfang der Zeichenfolge). Die Suche schlägt sofort fehl . Informationen zur Verwendung von!== false
-strrpos
im obigen Beispiel wird 0 oder false und kein anderer Wert zurückgegeben. Ebenso kannstrpos
im obigen Beispiel$temp
(die erwartete Position) oder false zurückgegeben werden. Ich habe mich!== false
für Konsistenz entschieden, aber Sie konnten=== 0
bzw.=== $temp
in den Funktionen verwenden.Aktualisiert am 23.08.2016
Funktionen
Tests
Ergebnisse (PHP 7.0.9)
(Am schnellsten bis am langsamsten sortiert)
Ergebnisse (PHP 5.3.29)
(Am schnellsten bis am langsamsten sortiert)
Starts mit_benchmark.php
quelle
function startswith5b($haystack, $needle) {return ($haystack{0}==$needle{0})?strncmp($haystack, $needle, strlen($needle)) === 0:FALSE;}
Ich habe unten eine Antwort hinzugefügt.So weit Alle Antworten Lasten unnötiger Arbeit zu tun scheinen,
strlen calculations
,string allocations (substr)
usw. Das'strpos'
und'stripos'
Funktionen geben den Index des ersten Auftretens$needle
in$haystack
:quelle
endsWith()
Funktion hat einen Fehler. Seine erste Zeile sollte (ohne -1) sein:$expectedPosition = strlen($haystack) - strlen($needle);
strpos($haystack, "$needle", 0)
ob es eine Chance gibt, dass es sich nicht bereits um eine Zeichenfolge handelt (z. B. wenn sie von stammtjson_decode()
). Andernfalls kann das [ungerade] Standardverhalten vonstrpos()
zu unerwarteten Ergebnissen führen: " Wenn die Nadel keine Zeichenfolge ist, wird sie in eine Ganzzahl konvertiert und als Ordnungswert eines Zeichens angewendet. "Gutschrift an :
Überprüfen Sie, ob eine Zeichenfolge mit einer anderen Zeichenfolge endet
Überprüfen Sie, ob eine Zeichenfolge mit einer anderen Zeichenfolge beginnt
quelle
Der Regex funktioniert oben, aber mit den anderen oben ebenfalls vorgeschlagenen Verbesserungen:
quelle
Diese Frage hat bereits viele Antworten, aber in einigen Fällen können Sie sich mit etwas Einfacherem als allen zufrieden geben. Wenn die gesuchte Zeichenfolge bekannt ist (fest codiert), können Sie reguläre Ausdrücke ohne Anführungszeichen usw. verwenden.
Überprüfen Sie, ob eine Zeichenfolge mit 'ABC' beginnt:
endet mit 'ABC':
In meinem einfachen Fall wollte ich überprüfen, ob eine Zeichenfolge mit einem Schrägstrich endet:
Der Vorteil: Da es sehr kurz und einfach ist, müssen Sie keine Funktion definieren (z
endsWith()
) wie oben gezeigt definieren.Aber nochmal - dies ist nicht für jeden Fall eine Lösung, nur für diesen sehr spezifischen.
quelle
@
damit der Schrägstrich (/
) nicht maskiert werden muss. Siehe Beispiel 3 hier: php.net/manual/en/function.preg-match.php .Wenn Geschwindigkeit für Sie wichtig ist, versuchen Sie dies (ich glaube, es ist die schnellste Methode)
Funktioniert nur für Strings und wenn $ haystack nur 1 Zeichen ist
quelle
endsWithChar('','x')
, aber das Ergebnis ist korrektHier sind zwei Funktionen, die keine temporäre Zeichenfolge einführen. Dies kann nützlich sein, wenn die Nadeln sehr groß sind:
quelle
endsWidth
sollte tunreturn $needle==='' || substr_compare(
... so funktioniert es wie erwartet, für-strlen($needle)===0
die, ohne das Update,endsWith('a','')
zurückkehrtfalse
substr_compare()
, also habe ich eine PR hinzugefügt , um das zu beheben :)endsWith('', 'foo')
löst eine Warnung aus: "substr_compare (): Die Startposition darf die anfängliche Zeichenfolgenlänge nicht überschreiten." Vielleicht ist das ein weiterer Fehlersubstr_compare()
, aber um ihn zu vermeiden, benötigen Sie eine|| (strlen($needle) <= strlen($haystack) && substr_compare(
) === 0);
return $needle === '' || @substr_compare(
.., um diese Warnung zu unterdrücken.Schnellste EndenWith () Lösung:
Benchmark:
Benchmark-Ergebnisse:
quelle
Mir ist klar, dass dies abgeschlossen ist, aber Sie können sich strncmp ansehen, da Sie so die Länge der Zeichenfolge zum Vergleichen angeben können.
quelle
Sie können
strpos
und verwendenstrrpos
quelle
strpos($sHaystack, $sNeedle) == 0
wie diesstrpos($sHaystack, $sNeedle) === 0
? Ich sehe einen Fehler, wennfalse == 0
ausgewertet wirdtrue
.Hier ist eine Multi-Byte-sichere Version der akzeptierten Antwort. Sie funktioniert gut für UTF-8-Zeichenfolgen:
quelle
startsWith
sollte sein$length = mb_strlen($needle, 'UTF-8');
Kurze und leicht verständliche Einzeiler ohne reguläre Ausdrücke.
startWith () ist unkompliziert.
EndenWith () verwendet das etwas ausgefallene und langsame strrev ():
quelle
Wenn Sie sich auf startwith konzentrieren und sicher sind, dass die Zeichenfolgen nicht leer sind, beschleunigt das Hinzufügen eines Tests für das erste Zeichen vor dem Vergleich, die Zeichenfolge usw. die Dinge ein wenig:
Es ist irgendwie (20% -30%) schneller. Das Hinzufügen eines weiteren Char-Tests wie $ haystack {1} === $ Needle {1} scheint die Dinge nicht wesentlich zu beschleunigen, kann sogar langsamer werden.
===
scheint schneller als==
Bedingter Operator(a)?b:c
scheint schneller alsif(a) b; else c;
Für diejenigen, die fragen: "Warum nicht Strpos verwenden?" andere Lösungen als "unnötige Arbeit" bezeichnen
strpos ist schnell, aber nicht das richtige Werkzeug für diesen Job.
Zum Verständnis hier eine kleine Simulation als Beispiel:
Was macht der Computer "drinnen"?
Angenommen, strlen iteriert nicht die gesamte Zeichenfolge (aber selbst in diesem Fall) ist dies überhaupt nicht praktisch.
quelle
Ich hoffe, dass die folgende Antwort effizient und auch einfach sein kann:
quelle
Normalerweise gehe ich heutzutage mit einer Bibliothek wie underscore-php .
Die Bibliothek ist voll von anderen praktischen Funktionen.
quelle
Die Antwort von mpen ist unglaublich gründlich, aber leider hat der bereitgestellte Benchmark eine sehr wichtige und nachteilige Kontrolle.
Da jedes Byte in Nadeln und Heuhaufen völlig zufällig ist, beträgt die Wahrscheinlichkeit, dass sich ein Nadel-Heuhaufen-Paar im ersten Byte unterscheidet, 99,609375%, was bedeutet, dass sich im Durchschnitt etwa 99609 der 100000 Paare im ersten Byte unterscheiden . Mit anderen Worten, der Benchmark ist stark auf
startswith
Implementierungen ausgerichtet, die das erste Byte explizit prüfen, wie zstrncmp_startswith2
.Wenn die Testgenerierungsschleife stattdessen wie folgt implementiert wird:
Die Benchmark-Ergebnisse erzählen eine etwas andere Geschichte:
Natürlich ist dieser Benchmark möglicherweise noch nicht vollkommen unvoreingenommen, aber er testet die Effizienz der Algorithmen, wenn auch teilweise passende Nadeln gegeben werden.
quelle
Zusamenfassend:
quelle
Nur eine Empfehlung:
Diese zusätzliche Zeile, in der das erste Zeichen der Zeichenfolgen verglichen wird, kann dazu führen, dass der falsche Fall sofort zurückkehrt , wodurch viele Ihrer Vergleiche viel schneller werden (7x schneller, wenn ich gemessen habe). Im wahren Fall zahlen Sie für diese einzelne Leitung praktisch keinen Preis für die Leistung, daher denke ich, dass es sich lohnt, sie einzubeziehen. (In der Praxis schlagen die meisten Vergleiche fehl, wenn Sie viele Zeichenfolgen auf einen bestimmten Startblock testen, da Sie in einem typischen Fall nach etwas suchen.)
quelle
startsWith("123", "0")
gibttrue
Die
substr
Funktion kannfalse
in vielen Sonderfällen zurückgegeben werden. Hier ist meine Version, die sich mit folgenden Problemen befasst:Tests (
true
bedeutet gut):Auch die
substr_compare
Funktion ist einen Blick wert. http://www.php.net/manual/en/function.substr-compare.phpquelle
Dies kann funktionieren
Quelle: https://stackoverflow.com/a/4419658
quelle
Ich würde es so machen
quelle
Basierend auf der Antwort von James Black ist hier das Ende mit der Version:
Hinweis: Ich habe den if-else-Teil gegen James Blacks Funktion "DoesWith" ausgetauscht, da strncasecmp die Version von strncmp ist, bei der die Groß- und Kleinschreibung nicht berücksichtigt wird.
quelle
strrev()
ist kreativ , aber sehr teuer, vor allem wenn man Saiten mitreden ... 100Kb.===
statt==
, um sicher zu sein.0
ist gleichbedeutend mit vielen Dingen in PHP.Warum nicht das Folgende?
Ausgabe:
Beachten Sie,
strpos
dass false zurückgegeben wird, wenn die Nadel nicht im Heuhaufen gefunden wurde, und 0 zurückgegeben wird, wenn und nur wenn die Nadel bei Index 0 gefunden wurde (AKA am Anfang).Und hier endet mit:
In diesem Szenario ist keine Funktion startWith () as erforderlich
wird wahr oder falsch genau zurückgeben.
Es scheint seltsam, dass es so einfach ist, wenn all die wilden Funktionen hier weit verbreitet sind.
quelle
strpos()
ist langsam, außer wenn sie übereinstimmt.strncmp()
wäre in diesem Fall viel besser.Viele der vorherigen Antworten werden genauso gut funktionieren. Dies ist jedoch möglicherweise so kurz, wie Sie es schaffen und es tun lassen können, was Sie wollen. Sie geben nur an, dass Sie möchten, dass es "true" zurückgibt. Daher habe ich Lösungen eingefügt, die boolesches true / false und textuelles true / false zurückgeben.
quelle
'true'
und'false'
als Zeichenfolgen zurück, die beidetrue
im booleschen Sinne sind. Es ist ein gutes Muster für so etwas wie underhanded.xcott.com ;)Sie können auch reguläre Ausdrücke verwenden:
quelle
preg_quote($needle, '/')
.No-Copy und No-Intern-Loop:
quelle
Hier ist eine effiziente Lösung für PHP 4. Sie könnten schnellere Ergebnisse erzielen, wenn Sie PHP 5
substr_compare
anstelle von verwendenstrcasecmp(substr(...))
.quelle
Hierfür können Sie die Funktion fnmatch verwenden.
quelle