Soru Bir dizenin belirli bir sözcük içerip içermediğini nasıl kontrol edebilirim?


Düşünmek:

$a = 'How are you?';

if ($a contains 'are')
    echo 'true';

Yukarıdaki kodu aldığımı varsayalım, ifadeyi yazmanın doğru yolu nedir? if ($a contains 'are')?


2668


Menşei




Cevaplar:


Kullanabilirsiniz strpos() Bir stringin diğerini içerdiğini bulmak için kullanılan fonksiyon:

$a = 'How are you?';

if (strpos($a, 'are') !== false) {
    echo 'true';
}

Kullanımı unutmayın !== false kasıtlı; strpos() iğne dizesinin samanlık dizesinde başladığı ofseti veya boole değerini döndürür false iğne bulunamadıysa. 0 geçerli bir ofset ve 0 "falsey" olduğu için, daha basit yapıları kullanamayız. !strpos($a, 'are').


5448



bulduğum bir şey, "eğer", ilk kelime ise, yukarıdaki kod, "yanlış" kabul edilebilecek "0" döndürdüğü için başarısız olur! Bunu önlemek için şunu okumalısınız (strpos ("x". $ A, 'are')! == false) ..... - Darknight
@Darknight: Kullandığınızda "0" "false" kabul edilmez! ==. Sadece kullanırsanız dikkate alınır! =. - Milan Babuškov
Partiye çok geç, ama buna dikkat et. Bu aynı zamanda 'önemsiyor musunuz' dizesi için de geçerli olacaktır. - DTest
@DTest - iyi evet tabii ki dizge 'vardır' içerdiği için gerçek dönecektir. ARE kelimesi için özel olarak arıyorsanız, örneğin A'dan önce ve E'den sonra bir karakter veya boşluk olup olmadığını kontrol edin. - jsherk
Yukarıda çok iyi yorumlar! Asla kullanmam! = Ya da ==, her şeyden önce! == ve === en iyi seçenek (benim düşünceme göre) tüm yönleri dikkate aldım (hız, doğruluk vb.). - Melsi


Düzenli ifadeler kullanabilirsiniz, diğer kullanıcılar tarafından belirtildiği gibi strpos ile karşılaştırıldığında kelime eşleşmesi için daha iyidir, aynı zamanda ücret, bakım, bakış vb. Dizeler için de geçerli olacaktır. Bu, normal ifadede kelime sınırları kullanılarak basitçe önlenebilir.

Basit bir eşleşme böyle bir şeye benzeyebilir:

$a = 'How are you?';

if (preg_match('/\bare\b/',$a))
    echo 'true';

Performans tarafında, strpos yaklaşık üç kat daha hızlıdır ve aklımda, bir kerede bir milyon karşılaştırmayı yaptığımda, maçın 1.5 saniyesini aldım ve 0.5 saniye sürdü.


451



öneriniz için teşekkürler, kodunuz harika çalışıyor, ancak strpos işlevini kullanmayı tercih ediyorum. - Charles Yeung
@ Alexander.Plutov ikincisi bana bir -1 veriyorsun ve soru değil mi? cmon google cevap 2 saniye sürer google.com/... - Breezer
+1 Basit bir dizgeyi aramanın korkunç bir yolu, ancak SO için pek çok ziyaretçi kendi alt dizelerini aramanın herhangi bir yolunu arıyor ve öneri getirilmeye yardımcı oluyor. OP bile aşırı basitleştirilmiş olabilir - alternatiflerini bilmesini sağlayın. - SamGoody
Teknik olarak, soru nasıl bulunacağını soruyor kelimeler bir alt dize değil. Bu, normal ifadeleri kullanmam için bana yardımcı oldu. Alternatifler her zaman yararlıdır.
Cevap için +1 ve @ plutov.by yorumuna -1, çünkü strpos tek bir kontroldür, bu arada regexp aynı anda birçok kelimeyi kontrol edebilirsiniz: preg_match (/ are | you | not /) - albanx


İşte böyle durumlarda yararlı olan küçük bir yardımcı programdır

// returns true if $needle is a substring of $haystack
function contains($needle, $haystack)
{
    return strpos($haystack, $needle) !== false;
}

198



@RobinvanBaalen Aslında, kod okunabilirliğini geliştirebilir. Ayrıca, düşüşlerin “tarafsız” olanlar için değil de (çok) kötü cevaplar için olması gerekiyordu. - Xaqq
@RobinvanBaalen işlevleri neredeyse okunabilirlik tanımına göre (yaptığınız şeyin fikrini iletmek için). Hangisinin daha okunabilir olduğunu karşılaştırın: if ($email->contains("@") && $email->endsWith(".com)) { ... veya if (strpos($email, "@") !== false && substr($email, -strlen(".com")) == ".com") { ... - Brandin
Sonunda @RobinvanBaalen kuralların kırılması anlamına gelir. Aksi takdirde insanlar yeni şeyler yapmak için yeni yaratıcı yollarla gelmezlerdi :). Artı, zihninizi martinfowler.com gibi bir şeylerin etrafına sararken sorun yaşadığımı itiraf etmeliyim. Yapılması gereken en doğru şey, işleri kendiniz denemek ve hangi yaklaşımların en uygun olduğunu öğrenmek. - James P.
Başka bir fikir: Kolayca sarmalayabileceğiniz bir yardımcı fonksiyona sahip olmak hata ayıklamaya yardımcı olabilir. Ayrıca, üretim hizmetlerinde bu tür ek yükü ortadan kaldıran iyi optimize ediciler için ağlamayı da güçlendirir. Bu yüzden tüm fikirlerin geçerli puanları vardır. ;) - Tino
Tabii ki bu yararlıdır. Bunu teşvik etmelisin. PHP 100'de dize konumlarını bulmak için yeni ve daha hızlı bir yol varsa ne olur? Strpos'u çağırdığınız tüm yerleri değiştirmek ister misiniz? Veya sadece içerisindeki içeriklerini değiştirmek istiyor musunuz? - Cosmin


Bu cevapların çoğu, dizinizde bir alt dizenin görünüp görünmeyeceğini söylese de, belirli bir yeri arıyorsanız, genellikle istediğinizi belirtmezsiniz. sözcükve değil alt dize.

Fark ne? Alt dizeler başka bir deyişle görünebilir:

  • "Alan" ın başında "vardır"
  • "Tavşan" ın sonunda "vardır"
  • "Ücretler" in ortasında "vardır"

Bunu hafifletmenin bir yolu, düzenli bir ifadeyle birlikte kullanılmasıdır. kelime sınırları (\b):

function containsWord($str, $word)
{
    return !!preg_match('#\\b' . preg_quote($word, '#') . '\\b#i', $str);
}

Bu yöntem, yukarıda belirtilen aynı yanlış pozitiflere sahip değildir, ancak kendi kendine ait bazı kenar durumları vardır. Kelime sınırları, kelime olmayan karakterlerle eşleşir (\W), olmayan bir şey olacak a-z, A-Z, 0-9veya _. Bunun anlamı, rakamlar ve altçizgiler kelime karakterleri olarak sayılacak ve bunun gibi senaryolar başarısız olacaktır:

  • "Ne düşünüyorsun?"
  • "Onlar" in "lol" dunno wut bu are4? "

Eğer bundan daha doğru bir şey istiyorsanız, İngilizce sözdizimi ayrıştırma işlemine başlamalısınız ve bu oldukça büyük bir solucan kutusu olabilir (ve her zaman verilmeyen sözdiziminin uygun şekilde kullanıldığını varsayar).


113



Bu kanonik cevap olmalı. Çünkü aradığımız şey kelimeler ve yok altdizgelerin, regex uygundur. Bunu da ekleyeceğim \b iki şeyle eşleşir \W değil, bu onu bulmak için harika yapar kelimeler Bir dizede: Dizenin başlangıcına eşleşir (^) ve dizgenin sonu ($) - code_monk
Bu işe yaramıyor: 3v4l.org/vPk2V - Jimbo
Bu doğru cevap olmalı .. cevapların geri kalanı "umurunda" gibi bir dizede "vardır" bulur .. @Dest tarafından belirtildiği gibi - Robert Sinclair
@RobertSinclair Bu kadar kötü mü? Eğer "umurunda mı" dizesinin "evet" kelimesini içerip içermediğini sorsaydınız "evet" derdim. "Are" kelimesi açıkça bu dizenin bir alt dizisidir. "" "Den ayrı bir soru," umurunda mı "" "" dizesindeki kelimelerden biridir. - Paulpro
@Paulpro Her ne kadar OP, $ a bir cümle belirtmemişse de, bunun ima edildiğine eminim. Onun sorusu, Sözcüğün içindeki Kelimeyi nasıl tespit edeceğiydi. Bir kelime içinde bir kelime içeriyorsa, daha çok ilgisiz olacağımı varsayardım. - Robert Sinclair


Bir dizenin başka bir dizgi içerip içermediğini belirlemek için PHP işlevini kullanabilirsiniz. strpos ().

int strpos ( string $haystack , mixed $needle [, int $offset = 0 ] )

<?php

$haystack = 'how are you';
$needle = 'are';

if (strpos($haystack,$needle) !== false) {
    echo "$haystack contains $needle";
}

?>

DİKKAT:

Eğer aradığınız iğne samanlığın başındaysa, eğer 0 yaparsanız == işe yaramayacağını karşılaştır, yapman gerekecek ===

bir == işaret bir karşılaştırma ve soldaki değişken / ifade / sabiti sağa değişken / ifade / sabit ile aynı değere sahip olup olmadığını test eder.

bir === işareti, iki değişken / eksresyon / sabitin eşit olup olmadığını görmek için bir karşılaştırma ANDAynı türe sahip - yani her ikisi de dizgiler veya her ikisi de tamsayılardır.


93



alıntı kaynağı? maxi-pedia.com/string+contains+substring+PHP - btk


kullanma strstr() veya stristr() Eğer aramanız büyük / küçük harfe duyarlı değilse başka bir seçenek olacaktır.


57



Üzerinde bir not php.net/manual/en/function.strstr.php sayfa: Not: Yalnızca belirli bir iğnenin samanlık içinde olup olmadığını belirlemek istiyorsanız, bunun yerine daha hızlı ve daha az bellek yoğun işlevini strpos () kullanın. - Jo Smo
@tastro Bu konuda saygın kriterler var mı? - Wayne Whitty
Bu daha yavaş olabilir, ancak IMHO strstr($a, 'are') çirkin olmaktan çok daha zarif strpos($a, 'are') !== false. PHP'nin gerçekten ihtiyacı var str_contains() işlevi. - Paul Spiegel


Bakmak strpos():

<?php
    $mystring = 'abc';
    $findme   = 'a';
    $pos = strpos($mystring, $findme);

    // Note our use of ===. Simply, == would not work as expected
    // because the position of 'a' was the 0th (first) character.
    if ($pos === false) {
        echo "The string '$findme' was not found in the string '$mystring'.";
    }
    else {
        echo "The string '$findme' was found in the string '$mystring',";
        echo " and exists at position $pos.";
    }
?>

55





"Falsey" ve "truthy" problemlerinden kaçınmak istiyorsanız, substr_count'u kullanabilirsiniz:

if (substr_count($a, 'are') > 0) {
    echo "at least one 'are' is present!";
}

Bu, strpostan biraz daha yavaştır, ancak karşılaştırma problemlerinden kaçınır.


37