Menggunakan array sebagai jarum di strpos


91

Bagaimana Anda menggunakan strposuntuk array jarum saat mencari string? Sebagai contoh:

$find_letters = array('a', 'c', 'd');
$string = 'abcdefg';

if(strpos($string, $find_letters) !== false)
{
    echo 'All the letters are found in the string!';
}

Karena saat menggunakan ini tidak akan berhasil, alangkah baiknya jika ada yang seperti ini

Jawaban:


138

@Dave cuplikan yang diperbarui dari http://www.php.net/manual/en/function.strpos.php#107351

function strposa($haystack, $needles=array(), $offset=0) {
        $chr = array();
        foreach($needles as $needle) {
                $res = strpos($haystack, $needle, $offset);
                if ($res !== false) $chr[$needle] = $res;
        }
        if(empty($chr)) return false;
        return min($chr);
}

Cara Penggunaan:

$string = 'Whis string contains word "cheese" and "tea".';
$array  = array('burger', 'melon', 'cheese', 'milk');

if (strposa($string, $array, 1)) {
    echo 'true';
} else {
    echo 'false';
}

akan kembali true, karena array "cheese".

Pembaruan: Kode yang ditingkatkan dengan berhenti ketika jarum pertama ditemukan:

function strposa($haystack, $needle, $offset=0) {
    if(!is_array($needle)) $needle = array($needle);
    foreach($needle as $query) {
        if(strpos($haystack, $query, $offset) !== false) return true; // stop on first true result
    }
    return false;
}
$string = 'Whis string contains word "cheese" and "tea".';
$array  = array('burger', 'melon', 'cheese', 'milk');
var_dump(strposa($string, $array)); // will return true, since "cheese" has been found

1
@Arnaud, apa alat yang Anda sarankan?
Binyamin

5
Saya tidak yakin, tapi mungkin kita bisa maju dalam string dari $ offset, dan berhenti saat jarum pertama ditemukan. Pikirkan tentang teks besar yang penuh dengan "a". Ambil $ jarum = [a, b]. Fungsi Anda strposaakan berjalan melalui semua teks, tetapi itu tidak perlu! Apakah saya bisa dimengerti?
Arnaud

Terima kasih @Arnaud atas saran fitur! Saya sangat setuju dengan pentingnya saran Anda dan telah memperbarui jawaban saya dengan contoh kode yang ditingkatkan.
Binyamin

Ini bukan yang ingin saya katakan, karena dengan fungsi baru Anda $ needles = [b, a] masih memiliki masalah, dan sebagai tambahan fungsi tersebut tidak lagi mengembalikan posisi kejadian pertama. Mari saya jelaskan lebih banyak. Asumsikan bahwa stringnya adalah "ABCDEF", dan jarumnya adalah C dan F. Apa yang bisa kita lakukan adalah menjalankan string tersebut: A, B ... C! Kami mendeteksi C, jadi kami berhenti di sini dan kami dapat mengembalikan posisi kemunculan pertama jarum, yaitu 2. Ini bisa bekerja dengan lebih dari string karakter tunggal, tetapi saya belum memikirkan implementasi yang tepat.
Arnaud

1
Saya meningkatkan kode dengan mengubah foreach($needle as $k => $query) { if(strpos($haystack, $query, $offset) !== false) return $k; }, sehingga mengembalikan kunci dari item yang cocok untuk penanganan lebih lanjut.
James Cameron

53

str_replace jauh lebih cepat.

$find_letters = array('a', 'c', 'd');
$string = 'abcdefg';
$match = (str_replace($find_letters, '', $string) != $string);

kesalahan sintaks: 1 tanda kurung tutup terlalu banyak pada baris # 3 (saya tidak dapat memperbaikinya secara langsung pada kode di atas karena> 6 persyaratan edit karakter;))
richey

1
Ups, itu salah. Diperbaiki sekarang. Cheers for the head up!
Leon

7
salah satu solusi terhebat!
andys

18

Kode di bawah ini tidak hanya menunjukkan bagaimana melakukannya, tetapi juga menempatkannya dalam fungsi yang mudah digunakan ke depannya. Itu ditulis oleh "jesda". (Saya menemukannya online)

Kode PHP:

<?php
/* strpos that takes an array of values to match against a string
 * note the stupid argument order (to match strpos)
 */
function strpos_arr($haystack, $needle) {
    if(!is_array($needle)) $needle = array($needle);
    foreach($needle as $what) {
        if(($pos = strpos($haystack, $what))!==false) return $pos;
    }
    return false;
}
?>

Pemakaian:

$needle = array('something','nothing');
$haystack = "This is something";
echo strpos_arr($haystack, $needle); // Will echo True

$haystack = "This isn't anything";
echo strpos_arr($haystack, $needle); // Will echo False 

Saya percaya ini hanya mengembalikan posisi pertama yang ditemukannya. Adakah saran tentang cara mengubahnya untuk mengembalikan posisi setiap jarum di tumpukan jerami?
Chaya Cooper

7

Anda dapat melakukan iterasi melalui larik dan menetapkan nilai "bendera" jika strposdikembalikan false.

$flag = false;
foreach ($find_letters as $letter)
{
    if (strpos($string, $letter) === false)
    {
        $flag = true;
    }
}

Kemudian periksa nilai $flag.


6
bukankah seharusnya begitu !== flase?
Joe Huang

Seharusnya! == salah. Kecuali jika Anda melanggar tepat setelah Anda menyetel benderanya ke true. Dan kemudian harus menafsirkan bendera sebagai Peringatan bahwa jarum tidak ada di tumpukan jerami. Itu berarti apa yang Anda coba capai adalah memeriksa bahwa semua jarum Anda ada di tumpukan jerami. Yang bukan pertanyaannya. Jadi .. ya. ! == false
Kevin Gagnon

5

Jika Anda hanya ingin memeriksa apakah karakter tertentu benar-benar ada dalam string atau tidak, gunakan strtok :

$string = 'abcdefg';
if (strtok($string, 'acd') === $string) {
    // not found
} else {
    // found
}

Jawaban luar biasa - JAUH lebih cepat dieksekusi daripada beberapa strpos (), misalnya, if (strpos ($ string, "a")! == false && strpos ($ string, "c")! == false && strpos ($ string, " d ")! == false)
The One and Only ChemistryBlob

5

Pertanyaannya, apakah contoh yang diberikan hanya berupa "contoh" atau persis seperti yang Anda cari? Ada banyak jawaban yang beragam di sini, dan saya tidak memahami kerumitan dari jawaban yang diterima.

Untuk mengetahui apakah konten SETIAP dari array jarum ada dalam string, dan dengan cepat mengembalikan benar atau salah:

$string = 'abcdefg';

if(str_replace(array('a', 'c', 'd'), '', $string) != $string){
    echo 'at least one of the needles where found';
};

Jika demikian, berikan kredit @Leon untuk itu.

Untuk mengetahui apakah SEMUA nilai dari array jarum ada dalam string, seperti dalam kasus ini, ketiganya 'a', 'b'dan 'c'HARUS ada, seperti yang Anda sebutkan sebagai "contoh"

echo 'Semua huruf ditemukan dalam string!';

Banyak jawaban di sini berada di luar konteks itu, tetapi saya ragu bahwa intensi pertanyaan yang Anda tandai sebagai terselesaikan. Misalnya, jawaban yang diterima adalah jarum

$array  = array('burger', 'melon', 'cheese', 'milk');

Bagaimana jika semua kata itu HARUS ditemukan dalam string?

Kemudian Anda mencoba beberapa "not accepted answers"di halaman ini.


Ini bekerja dengan sempurna untuk saya karena saya melihat array saya berisi sub-string. Saya diselamatkan dari menulis perintah sql seperti "% $ string%"
Maurice Elagu

4

Ekspresi ini mencari semua huruf:

count(array_filter( 
    array_map("strpos", array_fill(0, count($letters), $str), $letters),
"is_int")) == count($letters)

3

Anda dapat mencoba ini:

function in_array_strpos($word, $array){

foreach($array as $a){

    if (strpos($word,$a) !== false) {
        return true;
    }
}

return false;
}

1

Anda juga dapat mencoba menggunakan strpbrk () untuk negasi (tidak ada huruf yang ditemukan):

$find_letters = array('a', 'c', 'd');
$string = 'abcdefg';

if(strpbrk($string, implode($find_letters)) === false)
{
    echo 'None of these letters are found in the string!';
}

1

Ini adalah pendekatan saya. Iterasi karakter dalam string sampai ditemukan kecocokan. Pada rangkaian jarum yang lebih besar, ini akan mengungguli jawaban yang diterima karena tidak perlu memeriksa setiap jarum untuk menentukan bahwa kecocokan telah ditemukan.

function strpos_array($haystack, $needles = [], $offset = 0) {
    for ($i = $offset, $len = strlen($haystack); $i < $len; $i++){
        if (in_array($haystack[$i],$needles)) {
            return $i;
        }
    }
    return false;
}

Saya membandingkan ini dengan jawaban yang diterima dan dengan array lebih dari 7 $needlesini secara dramatis lebih cepat.


0

Dengan kode berikut:

$flag = true;
foreach($find_letters as $letter)
    if(false===strpos($string, $letter)) {
        $flag = false; 
        break;
    }

Kemudian periksa nilai $flag. Jika ya true, semua surat telah ditemukan. Jika tidak, ya false.


0

Saya menulis jawaban baru yang mudah-mudahan membantu siapa pun yang mencari yang serupa dengan saya.

Ini berfungsi dalam kasus "Saya memiliki banyak jarum dan saya mencoba menggunakannya untuk menemukan string tunggal". dan inilah pertanyaan yang saya temukan untuk menemukannya.

    $i = 0;
    $found = array();
    while ($i < count($needle)) {
        $x = 0;
        while ($x < count($haystack)) {
            if (strpos($haystack[$x], $needle[$i]) !== false) {
                array_push($found, $haystack[$x]);
            }
            $x++;
        }
        $i++;
    }

    $found = array_count_values($found);

Array $foundakan berisi daftar semua jarum yang cocok, item dari array dengan nilai hitungan tertinggi akan menjadi string yang Anda cari, Anda bisa mendapatkannya dengan:

print_r(array_search(max($found), $found));

0

Balas ke @binyamin dan @Timo .. (poin tidak cukup untuk menambahkan komentar ..) tetapi hasilnya tidak mengandung posisi ..
Kode di bawah ini akan mengembalikan posisi sebenarnya dari elemen pertama yang dimaksudkan untuk strpos melakukan. Ini berguna jika Anda mengharapkan untuk menemukan tepat 1 yang cocok .. Jika Anda mengharapkan untuk menemukan beberapa kecocokan, maka posisi pertama ditemukan mungkin tidak ada artinya.

function strposa($haystack, $needle, $offset=0) {
    if(!is_array($needle)) $needle = array($needle);
    foreach($needle as $query) {
      $res=strpos($haystack, $query, $offset);
      if($res !== false) return $res; // stop on first true result
    }
    return false;
}

0

Hanya peningkatan dari jawaban di atas

function strsearch($findme, $source){
    if(is_array($findme)){
        if(str_replace($findme, '', $source) != $source){
            return true;
        }
    }else{
        if(strpos($source,$findme)){
            return true;
        }
    }
    return false;
}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.