Frage startsWith () und endsWith () funktionieren in PHP


Wie kann ich zwei Funktionen schreiben, die eine Zeichenfolge aufnehmen und zurückgeben, wenn sie mit dem angegebenen Zeichen / String beginnt oder damit endet?

Beispielsweise:

$str = '|apples}';

echo startsWith($str, '|'); //Returns true
echo endsWith($str, '}'); //Returns true

1215
2018-05-07 12:14


Ursprung


Antworten:


function startsWith($haystack, $needle)
{
     $length = strlen($needle);
     return (substr($haystack, 0, $length) === $needle);
}

function endsWith($haystack, $needle)
{
    $length = strlen($needle);

    return $length === 0 || 
    (substr($haystack, -$length) === $needle);
}

Verwenden Sie dies, wenn Sie keine Regex verwenden möchten.


1291
2018-05-07 12:24



Es ist möglich zu verwenden strrpos und strpos Start-With und End-With jeweils überprüfen.

Beachten Sie, dass mit strrpos zu überprüfen beginnt mit und strpos Um die Enden zu überprüfen, werde ich so schnell wie möglich zurückkehren, anstatt die ganze Saite bis zum Ende zu überprüfen. Diese Lösung erstellt keine temporäre Zeichenfolge. Erwägen Sie, den Grund vor dem Abstimmen zu erklären. Nur weil ein f-wit an der DWTF nicht versteht, wie diese Funktion funktioniert oder denkt, dass es nur eine Lösung gibt, bedeutet das nicht, dass diese Antwort falsch ist.

function startsWith($haystack, $needle) {
    // search backwards starting from haystack length characters from the end
    return $needle === ''
      || strrpos($haystack, $needle, -strlen($haystack)) !== false;
}

function endsWith($haystack, $needle) {
    // search forward starting from end minus needle length characters
    if ($needle === '') {
        return true;
    }
    $diff = \strlen($haystack) - \strlen($needle);
    return $diff >= 0 && strpos($haystack, $needle, $diff) !== false;
}

Tests und Ergebnisse (vergleichen Sie das):

startsWith('abcdef', 'ab') -> true
startsWith('abcdef', 'cd') -> false
startsWith('abcdef', 'ef') -> false
startsWith('abcdef', '') -> true
startsWith('', 'abcdef') -> false

endsWith('abcdef', 'ab') -> false
endsWith('abcdef', 'cd') -> false
endsWith('abcdef', 'ef') -> true
endsWith('abcdef', '') -> true
endsWith('', 'abcdef') -> false

Beachten Sie das strncmp und substr_compare Funktionen werden diese Funktion übertreffen.


936
2018-05-06 18:22



Aktualisiert am 23. August 2016

Funktionen

function substr_startswith($haystack, $needle) {
    return substr($haystack, 0, strlen($needle)) === $needle;
}

function preg_match_startswith($haystack, $needle) {
    return preg_match('~' . preg_quote($needle, '~') . '~A', $haystack) > 0;
}

function substr_compare_startswith($haystack, $needle) {
    return substr_compare($haystack, $needle, 0, strlen($needle)) === 0;
}

function strpos_startswith($haystack, $needle) {
    return strpos($haystack, $needle) === 0;
}

function strncmp_startswith($haystack, $needle) {
    return strncmp($haystack, $needle, strlen($needle)) === 0;
}

function strncmp_startswith2($haystack, $needle) {
    return $haystack[0] === $needle[0]
        ? strncmp($haystack, $needle, strlen($needle)) === 0
        : false;
}

Tests

echo 'generating tests';
for($i = 0; $i < 100000; ++$i) {
    if($i % 2500 === 0) echo '.';
    $test_cases[] = [
        random_bytes(random_int(1, 7000)),
        random_bytes(random_int(1, 3000)),
    ];
}
echo "done!\n";


$functions = ['substr_startswith', 'preg_match_startswith', 'substr_compare_startswith', 'strpos_startswith', 'strncmp_startswith', 'strncmp_startswith2'];
$results = [];

foreach($functions as $func) {
    $start = microtime(true);
    foreach($test_cases as $tc) {
        $func(...$tc);
    }
    $results[$func] = (microtime(true) - $start) * 1000;
}

asort($results);

foreach($results as $func => $time) {
    echo "$func: " . number_format($time, 1) . " ms\n";
}

Ergebnisse (PHP 7.0.9)

(Sortiert am schnellsten zum langsamsten)

strncmp_startswith2: 40.2 ms
strncmp_startswith: 42.9 ms
substr_compare_startswith: 44.5 ms
substr_startswith: 48.4 ms
strpos_startswith: 138.7 ms
preg_match_startswith: 13,152.4 ms

Ergebnisse (PHP 5.3.29)

(Sortiert am schnellsten zum langsamsten)

strncmp_startswith2: 477.9 ms
strpos_startswith: 522.1 ms
strncmp_startswith: 617.1 ms
substr_compare_startswith: 706.7 ms
substr_startswith: 756.8 ms
preg_match_startswith: 10,200.0 ms

startswith_benchmark.php


217
2017-08-24 00:07



Alle Antworten scheinen bisher unnötige Arbeit zu leisten, strlen calculations, string allocations (substr)usw. 'strpos' und 'stripos' Funktionen geben den Index des ersten Auftretens von $needle im $haystack:

function startsWith($haystack,$needle,$case=true)
{
    if ($case)
        return strpos($haystack, $needle, 0) === 0;

    return stripos($haystack, $needle, 0) === 0;
}

function endsWith($haystack,$needle,$case=true)
{
    $expectedPosition = strlen($haystack) - strlen($needle);

    if ($case)
        return strrpos($haystack, $needle, 0) === $expectedPosition;

    return strripos($haystack, $needle, 0) === $expectedPosition;
}

127
2018-05-13 21:23



function startsWith($haystack, $needle, $case = true) {
    if ($case) {
        return (strcmp(substr($haystack, 0, strlen($needle)), $needle) === 0);
    }
    return (strcasecmp(substr($haystack, 0, strlen($needle)), $needle) === 0);
}

function endsWith($haystack, $needle, $case = true) {
    if ($case) {
        return (strcmp(substr($haystack, strlen($haystack) - strlen($needle)), $needle) === 0);
    }
    return (strcasecmp(substr($haystack, strlen($haystack) - strlen($needle)), $needle) === 0);
}

Kredit an:

Überprüfen Sie, ob eine Zeichenfolge mit einer anderen Zeichenfolge endet

Überprüfen Sie, ob eine Zeichenfolge mit einer anderen Zeichenfolge beginnt


45
2018-05-07 12:15



Der Regex funktioniert oben, aber mit den anderen oben vorgeschlagenen Verbesserungen:

 function startsWith($needle, $haystack) {
     return preg_match('/^' . preg_quote($needle, '/') . '/', $haystack);
 }

 function endsWith($needle, $haystack) {
     return preg_match('/' . preg_quote($needle, '/') . '$/', $haystack);
 }

24
2018-06-19 16:11



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 lang ist

function startsWithChar($needle, $haystack)
{
   return ($needle[0] === $haystack);
}

function endsWithChar($needle, $haystack)
{
   return ($needle[strlen($needle) - 1] === $haystack);
}

$str='|apples}';
echo startsWithChar($str,'|'); //Returns true
echo endsWithChar($str,'}'); //Returns true
echo startsWithChar($str,'='); //Returns false
echo endsWithChar($str,'#'); //Returns false

21
2017-12-15 08:53



Ich weiß, das ist vorbei, aber vielleicht möchten Sie es sich ansehen strncmp wie es Ihnen erlaubt, die Länge der Zeichenfolge zu vergleichen, gegen:

function startsWith($haystack, $needle, $case=true) {
    if ($case)
        return strncasecmp($haystack, $needle, strlen($needle)) == 0;
    else
        return strncmp($haystack, $needle, strlen($needle)) == 0;
}    

15
2017-09-17 02:50



Hier sind zwei Funktionen, die keine temporäre Zeichenfolge einführen, was nützlich sein könnte, wenn Nadeln im Wesentlichen groß sind:

function startsWith($haystack, $needle)
{
    return strncmp($haystack, $needle, strlen($needle)) === 0;
}

function endsWith($haystack, $needle)
{
    return $needle === '' || substr_compare($haystack, $needle, -strlen($needle)) === 0;
}

15
2017-08-02 07:40



Diese Frage hat bereits viele Antworten, aber in einigen Fällen können Sie sich mit etwas einfacherem als allen zufrieden geben. Wenn die Zeichenfolge, nach der Sie suchen, bekannt ist (hardcoded), können Sie reguläre Ausdrücke ohne Anführungszeichen usw. verwenden.

Überprüfen Sie, ob eine Zeichenfolge mit 'ABC' beginnt:

preg_match('/^ABC/', $myString); // "^" here means beginning of string

endet mit 'ABC':

preg_match('/ABC$/', $myString); // "$" here means end of string

In meinem einfachen Fall wollte ich überprüfen, ob eine Zeichenfolge mit einem Schrägstrich endet:

preg_match('/\/$/', $myPath);   // slash has to be quoted

Der Vorteil: Da es sehr kurz und einfach ist, müssen Sie keine Funktion definieren (z. B. endsWith()) wie oben gezeigt.

Aber wieder - das ist keine Lösung für jeden Fall, nur für diesen ganz bestimmten Fall.


13
2018-01-06 08:59