Pertanyaan startsWith () dan endsWith () berfungsi dalam PHP


Bagaimana saya bisa menulis dua fungsi yang akan mengambil string dan kembali jika dimulai dengan karakter / string yang ditentukan atau diakhiri dengan itu?

Sebagai contoh:

$str = '|apples}';

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

1215
2018-05-07 12:14


asal


Jawaban:


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);
}

Gunakan ini jika Anda tidak ingin menggunakan regex.


1291
2018-05-07 12:24



Itu mungkin untuk digunakan strrpos dan strpos untuk memeriksa mulai-dengan dan diakhiri dengan masing-masing.

Perhatikan bahwa menggunakan strrpos untuk memeriksa dimulai dengan dan strpos untuk memeriksa berakhir dengan akan kembali secepat mungkin daripada memeriksa seluruh string sampai akhir. Juga, solusi ini tidak membuat string sementara. Pertimbangkan untuk menjelaskan alasannya sebelum menurunkan. Hanya karena f-wit di DWTF tidak mengerti bagaimana fungsi ini berfungsi atau berpikir hanya ada satu solusi tidak berarti jawaban ini salah.

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;
}

Tes dan hasil (bandingkan dengan ini):

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

Catatan: strncmp dan substr_compare fungsi akan mengungguli fungsi ini.


936
2018-05-06 18:22



Diperbarui 23-Aug-2016

Fungsi

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;
}

Tes

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";
}

Hasil (PHP 7.0.9)

(Diurutkan paling cepat hingga paling lambat)

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

Hasil (PHP 5.3.29)

(Diurutkan paling cepat hingga paling lambat)

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



Semua jawaban sejauh ini tampaknya melakukan banyak pekerjaan yang tidak perlu, strlen calculations, string allocations (substr), dll 'strpos' dan 'stripos' fungsi mengembalikan indeks kejadian pertama $needle di $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 untuk:

Periksa apakah string berakhir dengan string lain

Periksa apakah string dimulai dengan string lain


45
2018-05-07 12:15



Fungsi regex di atas, tetapi dengan tweak lainnya juga disarankan di atas:

 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



Jika kecepatan penting bagi Anda, cobalah ini. (Saya percaya itu adalah metode tercepat)

Hanya berfungsi untuk string dan jika $ haystack hanya 1 karakter

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



Saya menyadari ini telah selesai, tetapi Anda mungkin ingin melihat strncmp karena memungkinkan Anda menempatkan panjang string untuk dibandingkan, jadi:

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



Berikut adalah dua fungsi yang tidak memperkenalkan string sementara, yang bisa berguna ketika jarum secara substansial besar:

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



Pertanyaan ini sudah memiliki banyak jawaban, tetapi dalam beberapa kasus Anda dapat menerima sesuatu yang lebih sederhana daripada semuanya. Jika string yang Anda cari dikenal (hardcoded), Anda dapat menggunakan ekspresi reguler tanpa mengutip apa pun, dll.

Periksa apakah string dimulai dengan 'ABC':

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

diakhiri dengan 'ABC':

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

Dalam kasus sederhana saya, saya ingin memeriksa apakah string berakhir dengan garis miring:

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

Keuntungan: karena sangat singkat dan sederhana, Anda tidak perlu mendefinisikan fungsi (seperti endsWith()) seperti yang ditunjukkan di atas.

Tetapi sekali lagi - ini bukan solusi untuk setiap kasus, hanya ini yang sangat spesifik.


13
2018-01-06 08:59



Kamu dapat memakai strpos dan strrpos 

$bStartsWith = strpos($sHaystack, $sNeedle) == 0;
$bEndsWith = strrpos($sHaystack, $sNeedle) == strlen($sHaystack)-strlen($sNeedle);

10
2018-05-12 12:36