Bir diziyi strposlarda iğneler olarak kullanma


91

strposBir dizi ararken iğne dizisi için nasıl kullanılır ? Örneğin:

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

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

Çünkü bunu kullanırken işe yaramaz, böyle bir şey olsaydı iyi olurdu

Yanıtlar:


138

@ Http://www.php.net/manual/en/function.strpos.php#107351 adresinden güncellenmiş bir pasaj gönderin.

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

Nasıl kullanılır:

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

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

truenedeniyle geri dönecek array "cheese".

Güncelleme: İğnelerin ilki bulunduğunda durdurmalı iyileştirilmiş kod:

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, önerilen uygulamanız nedir?
Binyamin

5
Emin değilim, ama belki $ offset'ten dizide ilerleyebilir ve iğnelerden ilki bulunduğunda durabiliriz. "A" ile dolu büyük bir metin düşünün. $ İğneler = [a, b] alın. Fonksiyonunuz strposametnin tamamı boyunca çalışacaktır, ancak gerekli değildir! Anlaşılabilir miyim?
Arnaud

Özellik önerisi için teşekkürler @Arnaud! Önerinizin önemine tamamen katılıyorum ve cevabımı geliştirilmiş kod örneği ile güncelledim.
Binyamin

Bu tam olarak söylemek istediğim şey değil, çünkü yeni işleviniz $ iğneler = [b, a] ile ilgili henüz bir sorun var ve ek olarak işlev artık ilk oluşumun konumunu döndürmüyor. Biraz daha açıklayayım. İpin "ABCDEF" olduğunu ve iğnelerin C ve F olduğunu varsayalım. Yapabileceğimiz şey, ipte dolaşmaktır: A, B ... C! C'yi tespit ederiz, bu yüzden burada dururuz ve bir iğnenin ilk oluşumunun konumuna geri dönebiliriz, yani 2'dir. Tek karakterli dizilerden daha fazlasıyla çalışabilir, ancak tam olarak uygulanmasını düşünmedim.
Arnaud

1
Kodu değiştirerek iyileştirdim foreach($needle as $k => $query) { if(strpos($haystack, $query, $offset) !== false) return $k; }, böylece daha fazla işlem için eşleşen öğenin anahtarını döndürür.
James Cameron

54

str_replace önemli ölçüde daha hızlıdır.

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

sözdizimi hatası:;) 1 kapanış ayracı çok fazla hattında 3. (I dolayı yukarıdaki kodda doğrudan> 6 karakter düzenleme gereksinimi düzeltmek olamazdı)
richey

1
Oops, bu manşetten çıktı. Şimdi düzeltildi. Uyarılar için şerefe!
Leon

8
en büyük çözümlerden biri!
andys

18

Aşağıdaki kod sadece nasıl yapılacağını göstermekle kalmaz, aynı zamanda ileriye dönük kullanımı kolay bir işleve de sokar. "Jesda" tarafından yazılmıştır. (İnternette buldum)

PHP Kodu:

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

Kullanım:

$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 

Bunun sadece bulduğu 1. pozisyonu döndürdüğüne inanıyorum. Samanlıktaki her iğnenin konumunu döndürmek için nasıl ince ayar yapılacağına dair herhangi bir öneriniz var mı?
Chaya Cooper

7

Dizide yineleme yapabilir ve strposdönerse bir "bayrak" değeri ayarlayabilirsiniz false.

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

Ardından değerini kontrol edin $flag.


6
olması gerekmiyor !== flasemu?
Joe Huang

! == false olmalıdır. Bayrağınızı true olarak ayarladıktan hemen sonra kırmadığınız sürece. Ve sonra bayrağı samanlıkta iğne olmadığına dair bir Uyarı olarak yorumlamak zorunda kalacaktı. Bu, başarmaya çalıştığınız şeyin, tüm iğnelerinizin samanlıkta olup olmadığını kontrol etmek olduğu anlamına gelir. Soru bu değil. Yani evet. ! == false
Kevin Gagnon

5

Sadece belirli karakterlerin gerçekten dizede olup olmadığını kontrol etmek istiyorsanız, strtok kullanın :

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

İnanılmaz cevap - çoklu strpos () 'dan ÇOK daha hızlı yürütme, örneğin, if (strpos ($ string, "a")! == false && strpos ($ string, "c")! == false && strpos ($ string, " d ") == false)!
Bir ve Tek ChemistryBlob

5

Soru, verilen örnek sadece bir "örnek" mi yoksa tam olarak aradığınız şey mi? Burada pek çok karışık cevap var ve kabul edilenin karmaşıklığını anlamıyorum.

Dizide iğneler dizisinin HERHANGİ bir içeriğinin olup olmadığını öğrenmek ve hızlı bir şekilde doğru veya yanlış döndürmek için:

$string = 'abcdefg';

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

Eğer öyleyse, lütfen bunun için @Leon kredisi verin .

Öğrenmek için TÜM değerleri iğnelerin dizinin bulunduğu bu durumda olduğu gibi, dizede, her üç 'a', 'b've 'c'sen söz gibi, mevcut OLMALIDIR senin "örneğin" olarak

echo 'Tüm harfler dizede bulunur!';

Buradaki pek çok cevap bu bağlamın dışında, ancak çözülmüş olarak işaretlediğiniz sorunun amacından şüpheliyim. Örneğin, kabul edilen cevap şudur:

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

Ya tüm bu kelimelerin dizede bulunması ZORUNLUysa?

Sonra "not accepted answers"bu sayfada biraz deneyin .


Dizimin alt dizeler içerdiğine baktığım için bu benim için mükemmel çalıştı. "% $ String%" gibi sql komutunu yazmaktan kurtuldum
Maurice Elagu

4

Bu ifade tüm harfleri arar:

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

3

Bunu deneyebilirsiniz:

function in_array_strpos($word, $array){

foreach($array as $a){

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

return false;
}

1

Ayrıca olumsuzluk için strpbrk () kullanmayı deneyebilirsiniz ( harflerden hiçbiri bulunamadı):

$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

Bu benim yaklaşımım. Bir eşleşme bulunana kadar dizedeki karakterleri yineleyin. Daha geniş bir iğne dizisinde bu, kabul edilen cevabı geride bırakacaktır çünkü bir eşleşme bulunduğunu belirlemek için her iğneyi kontrol etmesi gerekmez.

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

Bunu kabul edilen yanıtla karşılaştırdım ve 7'den fazla bir dizi ile $needlesbu çarpıcı biçimde daha hızlıydı.


0

Aşağıdaki kodla:

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

Ardından değerini kontrol edin $flag. Eğer öyleyse true, tüm harfler bulunmuştur. Değilse, o false.


0

Yeni bir cevap yazıyorum ve umduğum gibi arayan herkese yardımcı olur.

Bu, "Birden fazla iğnem var ve bunları tek bir şerit bulmak için kullanmaya çalışıyorum" durumunda işe yarar. ve bunu bulmak için karşılaştığım soru bu.

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

Dizi $found, eşleşen tüm iğnelerin bir listesini içerecektir, en yüksek sayı değerine sahip dizinin öğesi, aradığınız dizeler olacaktır, bunu şununla elde edebilirsiniz:

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

0

@Binyamin ve @Timo .. için yanıt verin (yorum eklemek için yeterli puan yok ..) ancak sonuç konumu içermiyor ..
Aşağıdaki kod, strpos'un amaçladığı ilk öğenin gerçek konumunu döndürecektir yapmak. Bu, tam olarak 1 eşleşme bulmayı bekliyorsanız kullanışlıdır. Birden fazla eşleşme bulmayı bekliyorsanız, ilk bulunan konumu anlamsız olabilir.

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

Yukarıdaki cevaplardan sadece bir yükseltme

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;
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.