Penggunaan fungsi STARTSWITH pada PHP

Jika teman – teman sudah pernah belajar Pemrograman Java, pastinya tahu apa itu fungsi startsWith. Bagi yang belum pernah,,, menrut saya funsgi tersbut berguna untuk mengecek apakah dalam satu kalimat itu di awalai dengan kata yang kita cari. Misal ada nama Rendra Kurniawan, lalu kita cek, apakah nama tersebut diawali dengan kata Ucil, jika tidak maka false jika iya maka true. Fungsi ini menghasilkan nilai TRUE dan FALSE. Ok untuk scriptnya silahkan lihat di bawah ini :

Ok,, semoga bermanfaat ya teman – teman … 🙂

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

function startsWith[$haystack, $needle]
{
     $length = strlen[$needle];
     return [substr[$haystack, 0, $length] === $needle];
}

function endsWith[$haystack, $needle]
{
    $length = strlen[$needle];
    if [$length == 0] {
        return true;
    }

    return [substr[$haystack, -$length] === $needle];
}

Gunakan ini jika Anda tidak ingin menggunakan regex.

Anda dapat menggunakan substr_compare berfungsi untuk memeriksa mulai-dengan dan diakhiri dengan:

function startsWith[$haystack, $needle] {
    return substr_compare[$haystack, $needle, 0, strlen[$needle]] === 0;
}
function endsWith[$haystack, $needle] {
    return substr_compare[$haystack, $needle, -strlen[$needle]] === 0;
}

Ini harus menjadi salah satu solusi tercepat pada PHP 7 [ script benchmark ]. Diuji terhadap tumpukan jerami 8KB, berbagai jarum panjang dan penuh, sebagian dan tidak ada kotak korek api. strncmp adalah sentuhan yang lebih cepat untuk memulai-dengan tetapi tidak dapat mengecek ujung-dengan.

Diperbarui 23-Agu-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

Semua jawaban sejauh ini tampaknya melakukan banyak pekerjaan yang tidak perlu, strlen calculations, string allocations [substr], dll. Fungsi 'strpos' dan 'stripos' 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;
}

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 Ke :

Periksa apakah string berakhir dengan string lain

Periksa apakah string dimulai dengan string lain

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

Pertanyaan ini sudah memiliki banyak jawaban, tetapi dalam beberapa kasus Anda dapat menerima sesuatu yang lebih sederhana daripada semuanya. Jika string yang Anda cari diketahui [hardcoded], Anda dapat menggunakan ekspresi reguler tanpa mengutip 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 diakhiri dengan slash:

preg_match['#/$#', $myPath];   // Use "#" as delimiter instead of escaping slash

Keuntungannya: karena sangat pendek 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.

Jika kecepatan penting bagi Anda, coba ini. [Saya percaya ini 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

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

Saya menyadari ini telah selesai, tetapi Anda mungkin ingin melihat strncmp karena memungkinkan Anda untuk meletakkan 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;
}    

Solusi tercepat dengan solusi []:

# Checks if a string ends in a string
function endsWith[$haystack, $needle] {
    return substr[$haystack,-strlen[$needle]]===$needle;
}

Benchmark:

# This answer
function endsWith[$haystack, $needle] {
    return substr[$haystack,-strlen[$needle]]===$needle;
}

# Accepted answer
function endsWith2[$haystack, $needle] {
    $length = strlen[$needle];

    return $length === 0 ||
    [substr[$haystack, -$length] === $needle];
}

# Second most-voted answer
function endsWith3[$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;
}

# Regex answer
function endsWith4[$haystack, $needle] {
    return preg_match['/' . preg_quote[$needle, '/'] . '$/', $haystack];
}

function timedebug[] {
    $test = 10000000;

    $time1 = microtime[true];
    for [$i=0; $i < $test; $i++] {
        $tmp = endsWith['TestShortcode', 'Shortcode'];
    }
    $time2 = microtime[true];
    $result1 = $time2 - $time1;

    for [$i=0; $i < $test; $i++] {
        $tmp = endsWith2['TestShortcode', 'Shortcode'];
    }
    $time3 = microtime[true];
    $result2 = $time3 - $time2;

    for [$i=0; $i < $test; $i++] {
        $tmp = endsWith3['TestShortcode', 'Shortcode'];
    }
    $time4 = microtime[true];
    $result3 = $time4 - $time3;

    for [$i=0; $i < $test; $i++] {
        $tmp = endsWith4['TestShortcode', 'Shortcode'];
    }
    $time5 = microtime[true];
    $result4 = $time5 - $time4;

    echo $test.'x endsWith: '.$result1.' seconds # This answer
'; echo $test.'x endsWith2: '.$result4.' seconds # Accepted answer
'; echo $test.'x endsWith3: '.$result2.' seconds # Second most voted answer
'; echo $test.'x endsWith4: '.$result3.' seconds # Regex answer
'; exit; } timedebug[];

Hasil Benchmark:

10000000x endsWith: 1.5760900974274 seconds # This answer
10000000x endsWith2: 3.7102129459381 seconds # Accepted answer
10000000x endsWith3: 1.8731069564819 seconds # Second most voted answer
10000000x endsWith4: 2.1521229743958 seconds # Regex answer

Anda dapat menggunakan strpos dan strrpos

$bStartsWith = strpos[$sHaystack, $sNeedle] == 0;
$bEndsWith = strrpos[$sHaystack, $sNeedle] == strlen[$sHaystack]-strlen[$sNeedle];

One-liner pendek dan mudah dipahami tanpa ekspresi reguler.

dimulai dengan [] lurus ke depan.

function startsWith[$haystack, $needle] {
   return [strpos[$haystack, $needle] === 0];
}

endsWith [] menggunakan strrev yang agak mewah dan lambat []:

function endsWith[$haystack, $needle] {
   return [strpos[strrev[$haystack], strrev[$needle]] === 0];
}

Inilah versi aman multi-byte dari jawaban yang diterima, itu berfungsi dengan baik untuk string UTF-8:

function startsWith[$haystack, $needle]
{
    $length = mb_strlen[$needle, 'UTF-8'];
    return [mb_substr[$haystack, 0, $length, 'UTF-8'] === $needle];
}

function endsWith[$haystack, $needle]
{
    $length = mb_strlen[$needle, 'UTF-8'];
    return $length === 0 ||
        [mb_substr[$haystack, -$length, $length, 'UTF-8'] === $needle];
}

Berfokus pada permulaan dengan, jika Anda yakin string tidak kosong, menambahkan tes pada char pertama, sebelum perbandingan, strlen, dll., Mempercepat segalanya:

function startswith5b[$haystack, $needle] {
    return [$haystack{0}==$needle{0}]?strncmp[$haystack, $needle, strlen[$needle]] === 0:FALSE;
}

Itu entah bagaimana [20% -30%] lebih cepat. Menambahkan tes char lain, seperti $ haystack {1} === $ needle {1} tampaknya tidak mempercepat banyak hal, bahkan mungkin melambat.

=== tampaknya lebih cepat dari == operator bersyarat [a]?b:c tampaknya lebih cepat daripada if[a] b; else c;

Bagi mereka yang bertanya "mengapa tidak menggunakan strpos?" memanggil solusi lain "pekerjaan yang tidak perlu"

strpos cepat, tetapi itu bukan alat yang tepat untuk pekerjaan ini.

Untuk memahami, ini adalah sedikit simulasi sebagai contoh:

Search a12345678c inside bcdefga12345678xbbbbb.....bbbbba12345678c

Apa yang dilakukan komputer "di dalam"?

    With strccmp, etc...

    is a===b? NO
    return false



    With strpos

    is a===b? NO -- iterating in haysack
    is a===c? NO
    is a===d? NO
    ....
    is a===g? NO
    is a===g? NO
    is a===a? YES
    is 1===1? YES -- iterating in needle
    is 2===3? YES
    is 4===4? YES
    ....
    is 8===8? YES
    is c===x? NO: oh God,
    is a===1? NO -- iterating in haysack again
    is a===2? NO
    is a===3? NO
    is a===4? NO
    ....
    is a===x? NO
    is a===b? NO
    is a===b? NO
    is a===b? NO
    is a===b? NO
    is a===b? NO
    is a===b? NO
    is a===b? NO
    ...
    ... may many times...
    ...
    is a===b? NO
    is a===a? YES -- iterating in needle again
    is 1===1? YES
    is 2===3? YES
    is 4===4? YES
    is 8===8? YES
    is c===c? YES YES YES I have found the same string! yay!
    was it at position 0? NOPE
    What you mean NO? So the string I found is useless? YEs.
    Damn.
    return false

Dengan asumsi strlen tidak mengulangi seluruh string [tetapi bahkan dalam kasus itu] ini tidak nyaman sama sekali.

Saya biasanya berakhir dengan perpustakaan seperti underscore-php hari ini.

require_once["vendor/autoload.php"]; //use if needed
use Underscore\Types\String; 

$str = "there is a string";
echo[ String::startsWith[$str, 'the'] ]; // 1
echo[ String::endsWith[$str, 'ring']]; // 1   

Perpustakaan penuh dengan fungsi praktis lainnya.

answer oleh mpen sangat menyeluruh, tetapi, sayangnya, patokan yang diberikan memiliki pengawasan yang sangat penting dan merugikan.

Karena setiap byte dalam jarum dan tumpukan jerami benar-benar acak, probabilitas bahwa pasangan jarum-tumpukan jerami akan berbeda pada byte pertama adalah 99,609375%, yang berarti bahwa, rata-rata, sekitar 99609 dari 100.000 pasang akan berbeda pada byte pertama . Dengan kata lain, benchmark sangat bias terhadap implementasi startswith yang memeriksa byte pertama secara eksplisit, seperti yang dilakukan oleh strncmp_startswith2.

Jika loop menghasilkan tes diimplementasikan sebagai berikut:

echo 'generating tests';
for[$i = 0; $i < 100000; ++$i] {
    if[$i % 2500 === 0] echo '.';

    $haystack_length = random_int[1, 7000];
    $haystack = random_bytes[$haystack_length];

    $needle_length = random_int[1, 3000];
    $overlap_length = min[random_int[0, $needle_length], $haystack_length];
    $needle = [$needle_length > $overlap_length] ?
        substr[$haystack, 0, $overlap_length] . random_bytes[$needle_length - $overlap_length] :
        substr[$haystack, 0, $needle_length];

    $test_cases[] = [$haystack, $needle];
}
echo " done!
";

hasil benchmark menceritakan kisah yang sedikit berbeda:

strncmp_startswith: 223.0 ms
substr_startswith: 228.0 ms
substr_compare_startswith: 238.0 ms
strncmp_startswith2: 253.0 ms
strpos_startswith: 349.0 ms
preg_match_startswith: 20,828.7 ms

Tentu saja, tolok ukur ini mungkin masih tidak bias sempurna, tetapi ini menguji efisiensi algoritma ketika diberikan juga jarum yang cocok sebagian.

Saya harap jawaban di bawah ini bisa efisien dan juga sederhana:

$content = "The main string to search";
$search = "T";
//For compare the begining string with case insensitive. 
if[stripos[$content, $search] === 0] echo 'Yes';
else echo 'No';

//For compare the begining string with case sensitive. 
if[strpos[$content, $search] === 0] echo 'Yes';
else echo 'No';

//For compare the ending string with case insensitive. 
if[stripos[strrev[$content], strrev[$search]] === 0] echo 'Yes';
else echo 'No';

//For compare the ending string with case sensitive. 
if[strpos[strrev[$content], strrev[$search]] === 0] echo 'Yes';
else echo 'No';

Hanya rekomendasi:

function startsWith[$haystack,$needle] {
    if[$needle===""] return true;
    if[$haystack[0]$needle[0]] return false; // ------------------------- speed boost!
    return [0===substr_compare[$haystack,$needle,0,strlen[$needle]]];
}

Baris tambahan itu, yang membandingkan karakter pertama dari string, dapat membuat case palsu kembali segera , oleh karena itu membuat banyak perbandingan Anda jauh lebih cepat [7x lebih cepat ketika saya mengukur]. Dalam kasus yang sebenarnya Anda membayar hampir tidak ada harga dalam kinerja untuk satu baris jadi saya pikir itu layak termasuk. [Juga, dalam praktiknya, ketika Anda menguji banyak string untuk suatu starting starting tertentu, sebagian besar perbandingan akan gagal karena dalam kasus tipikal Anda sedang mencari sesuatu.]

Kenapa tidak mengikuti yang berikut?

//How to check if a string begins with another string
$haystack = "valuehaystack";
$needle = "value";
if [strpos[$haystack, $needle] === 0]{
    echo "Found " . $needle . " at the beginning of " . $haystack . "!";
}

Keluaran:

Nilai ditemukan di awal valuehaystack!

Ingat, strpos akan mengembalikan false jika jarum tidak ditemukan di tumpukan jerami, dan akan mengembalikan 0 jika, dan hanya jika, jarum ditemukan di indeks 0 [AKA awal].

Dan ini berakhir dengan:

$haystack = "valuehaystack";
$needle = "haystack";

//If index of the needle plus the length of the needle is the same length as the entire haystack.
if [strpos[$haystack, $needle] + strlen[$needle] === strlen[$haystack]]{
    echo "Found " . $needle . " at the end of " . $haystack . "!";
}

Dalam skenario ini tidak perlu untuk fungsi beginWith [] as

[strpos[$stringToSearch, $doesItStartWithThis] === 0]

akan mengembalikan benar atau salah secara akurat.

Tampaknya aneh ini sesederhana ini dengan semua fungsi liar yang merajalela di sini.

Fungsi substr dapat mengembalikan false dalam banyak kasus khusus, jadi inilah versi saya, yang membahas masalah ini:

function startsWith[ $haystack, $needle ]{
  return $needle === ''.substr[ $haystack, 0, strlen[ $needle ]]; // substr's false => empty string
}

function endsWith[ $haystack, $needle ]{
  $len = strlen[ $needle ];
  return $needle === ''.substr[ $haystack, -$len, $len ]; // ! len=0
}

Tes [true berarti baik]:

var_dump[ startsWith['','']];
var_dump[ startsWith['1','']];
var_dump[!startsWith['','1']];
var_dump[ startsWith['1','1']];
var_dump[ startsWith['1234','12']];
var_dump[!startsWith['1234','34']];
var_dump[!startsWith['12','1234']];
var_dump[!startsWith['34','1234']];
var_dump['---'];
var_dump[ endsWith['','']];
var_dump[ endsWith['1','']];
var_dump[!endsWith['','1']];
var_dump[ endsWith['1','1']];
var_dump[!endsWith['1234','12']];
var_dump[ endsWith['1234','34']];
var_dump[!endsWith['12','1234']];
var_dump[!endsWith['34','1234']];

Juga, fungsi substr_compare juga layak dilihat. //www.php.net/manual/en/function.substr-compare.php

pendeknya:

function startsWith[$str, $needle]{
   return substr[$str, 0, strlen[$needle]] === $needle;
}

function endsWith[$str, $needle]{
   $length = strlen[$needle];
   return !$length || substr[$str, - $length] === $needle;
}

Saya akan melakukannya seperti ini

     function startWith[$haystack,$needle]{
              if[substr[$haystack,0, strlen[$needle]]===$needle]
              return true;
        }

  function endWith[$haystack,$needle]{
              if[substr[$haystack, -strlen[$needle]]===$needle]
              return true;
        }

Anda juga dapat menggunakan ekspresi reguler:

function endsWith[$haystack, $needle, $case=true] {
  return preg_match["/.*{$needle}$/" . [[$case] ? "" : "i"], $haystack];
}

Banyak jawaban sebelumnya juga akan berfungsi. Namun, ini mungkin sesingkat yang Anda bisa dan lakukan apa yang Anda inginkan. Anda hanya menyatakan bahwa Anda ingin 'mengembalikan yang benar'. Jadi saya memasukkan solusi yang mengembalikan boolean true/false dan tekstual true/false.

// boolean true/false
function startsWith[$haystack, $needle]
{
    return strpos[$haystack, $needle] === 0 ? 1 : 0;
}

function endsWith[$haystack, $needle]
{
    return stripos[$haystack, $needle] === 0 ? 1 : 0;
}


// textual true/false
function startsWith[$haystack, $needle]
{
    return strpos[$haystack, $needle] === 0 ? 'true' : 'false';
}

function endsWith[$haystack, $needle]
{
    return stripos[$haystack, $needle] === 0 ? 'true' : 'false';
}

Berdasarkan jawaban James Black, inilah ujungnya dengan versi:

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

function endsWith[$haystack, $needle, $case=true] {
     return startsWith[strrev[$haystack],strrev[$needle],$case];

}

Catatan: Saya telah menukar bagian if-else untuk fungsi James Black beginWith, karena strncasecmp sebenarnya adalah versi case-insensitive dari strncmp.

Ini solusi yang efisien untuk PHP 4. Anda bisa mendapatkan hasil yang lebih cepat jika pada PHP 5 dengan menggunakan substr_compare alih-alih strcasecmp[substr[...]].

function stringBeginsWith[$haystack, $beginning, $caseInsensitivity = false]
{
    if [$caseInsensitivity]
        return strncasecmp[$haystack, $beginning, strlen[$beginning]] === 0;
    else
        return strncmp[$haystack, $beginning, strlen[$beginning]] === 0;
}

function stringEndsWith[$haystack, $ending, $caseInsensitivity = false]
{
    if [$caseInsensitivity]
        return strcasecmp[substr[$haystack, strlen[$haystack] - strlen[$ending]], $haystack] === 0;
    else
        return strpos[$haystack, $ending, strlen[$haystack] - strlen[$ending]] !== false;
}

Bài mới nhất

Chủ Đề