Mempertimbangkan:
$a = 'How are you?';
if ($a contains 'are')
echo 'true';
Misalkan saya memiliki kode di atas, apa cara yang benar untuk menulis pernyataan if ($a contains 'are')
?
Anda dapat menggunakan strpos()
fungsi yang digunakan untuk menemukan kemunculan satu string di dalam yang lain:
$a = 'How are you?';
if (strpos($a, 'are') !== false) {
echo 'true';
}
Perhatikan bahwa penggunaan !== false
disengaja (tidak != false
juga tidak === true
akan mengembalikan hasil yang diinginkan); strpos()
mengembalikan offset di mana string jarum dimulai di string tumpukan jerami, atau boolean false
jika jarum tidak ditemukan. Karena 0 adalah offset yang valid dan 0 adalah "falsey", kami tidak dapat menggunakan konstruksi yang lebih sederhana seperti !strpos($a, 'are')
.
strpos($a, 'are') > -1
untuk menguji kebenaran. Dari perspektif debugging, saya menemukan otak saya buang lebih sedikit siklus clock menentukan apakah garis ditulis dengan benar ketika saya tidak harus menghitung tanda sama dengan yang berdekatan.Anda dapat menggunakan ekspresi reguler, lebih baik untuk pencocokan kata dibandingkan dengan yang
strpos
disebutkan oleh pengguna lain, itu juga akan mengembalikan true untuk string seperti tarif, perawatan, tatapan, dll. Ini hanya dapat dihindari dalam ekspresi reguler dengan menggunakan batas kata.Pasangan yang cocok untuk dapat terlihat seperti ini:
Di sisi kinerja,
strpos
sekitar tiga kali lebih cepat dan ada dalam pikiran, ketika saya melakukan satu juta membandingkan sekaligus, butuhpreg_match
1,5 detik untuk menyelesaikan dan untukstrpos
itu butuh 0,5 detik.Sunting: Untuk mencari bagian mana pun dari string, bukan hanya kata demi kata, saya akan merekomendasikan menggunakan ungkapan biasa seperti
Pada
i
akhir ekspresi reguler mengubah ekspresi reguler menjadi tidak peka huruf besar-kecil, jika Anda tidak menginginkannya, Anda dapat mengabaikannya.Sekarang, ini bisa sangat bermasalah dalam beberapa kasus karena $ string pencarian tidak dibersihkan dengan cara apa pun, maksud saya, mungkin tidak lulus pemeriksaan dalam beberapa kasus seolah-olah
$search
input pengguna mereka dapat menambahkan beberapa string yang mungkin berperilaku seperti beberapa ekspresi reguler yang berbeda ...Juga, inilah alat yang hebat untuk menguji dan melihat penjelasan berbagai ekspresi reguler Regex101
Untuk menggabungkan kedua set fungsionalitas menjadi fungsi multi-fungsi tunggal (termasuk dengan sensitivitas case yang dapat dipilih), Anda dapat menggunakan sesuatu seperti ini:
sumber
Berikut adalah sedikit fungsi utilitas yang berguna dalam situasi seperti ini
sumber
if ($email->contains("@") && $email->endsWith(".com)) { ...
atauif (strpos($email, "@") !== false && substr($email, -strlen(".com")) == ".com") { ...
Meskipun sebagian besar jawaban ini akan memberi tahu Anda jika substring muncul di string Anda, biasanya itu bukan yang Anda inginkan jika Anda mencari kata tertentu , dan bukan substring .
Apa bedanya? Substring dapat muncul dengan kata lain:
Salah satu cara untuk mengurangi ini adalah dengan menggunakan ekspresi reguler ditambah dengan batas kata (
\b
):Metode ini tidak memiliki positif palsu yang sama dengan yang disebutkan di atas, tetapi metode ini memiliki beberapa kasus tepi sendiri. Batas kata cocok pada karakter non-kata (
\W
), yang akan menjadi sesuatu yang tidaka-z
,A-Z
,0-9
, atau_
. Itu berarti digit dan garis bawah akan dihitung sebagai karakter kata dan skenario seperti ini akan gagal:Jika Anda menginginkan sesuatu yang lebih akurat dari ini, Anda harus mulai melakukan parsing sintaksis bahasa Inggris, dan itu adalah sekaleng cacing yang cukup besar (dan mengasumsikan penggunaan sintaks yang tepat, yang tidak selalu diberikan).
sumber
\b
cocok dengan dua hal yang\W
tidak, yang membuatnya bagus untuk menemukan kata-kata dalam string: Itu cocok dengan awal string (^
) dan akhir string ($
)Untuk menentukan apakah string berisi string lain, Anda dapat menggunakan fungsi PHP strpos () .
int strpos ( string $haystack , mixed $needle [, int $offset = 0 ] )
PERINGATAN:
Jika jarum yang Anda cari ada di awal tumpukan jerami, ia akan kembali ke posisi 0, jika Anda melakukan
==
perbandingan yang tidak berfungsi, Anda harus melakukan===
Sebuah
==
tanda adalah perbandingan dan tes apakah variabel / ekspresi / konstan ke kiri memiliki nilai yang sama sebagai variabel / ekspresi / konstan ke kanan.Sebuah
===
tanda adalah perbandingan untuk melihat apakah dua variabel / expresions / konstanta yang samaAND
memiliki tipe yang sama - yaitu keduanya string atau keduanya adalah bilangan bulat.sumber
Lihatlah
strpos()
:sumber
Menggunakan
strstr()
ataustristr()
jika pencarian Anda harus case-sensitive akan menjadi pilihan lain.sumber
strstr($a, 'are')
jauh lebih elegan daripada yang jelekstrpos($a, 'are') !== false
. PHP sangat membutuhkanstr_contains()
fungsi.Manfaatkan pencocokan case-insensitve menggunakan
stripos()
:sumber
Mengintip komentar SamGoody dan Lego Stormtroopr.
Jika Anda mencari algoritma PHP untuk menentukan peringkat hasil pencarian berdasarkan kedekatan / relevansi beberapa kata, inilah cara cepat dan mudah untuk menghasilkan hasil pencarian hanya dengan PHP:
Masalah dengan metode pencarian boolean lain seperti
strpos()
,preg_match()
,strstr()
ataustristr()
Metode PHP berdasarkan Vector Space Model dan tf-idf (istilah frekuensi - frekuensi dokumen terbalik):
Kedengarannya sulit tetapi sangat mudah.
Jika kita ingin mencari beberapa kata dalam sebuah string, masalah intinya adalah bagaimana kita memberikan bobot pada masing-masing kata?
Jika kami dapat menimbang istilah dalam string berdasarkan seberapa representatifnya dari string secara keseluruhan, kami dapat memesan hasil kami dengan yang paling cocok dengan kueri.
Ini adalah gagasan model ruang vektor, tidak jauh dari cara kerja pencarian teks lengkap SQL:
KASUS 1
HASIL
KASUS 2
HASIL
KASUS 3
HASIL
Ada banyak perbaikan yang harus dilakukan tetapi model tersebut menyediakan cara untuk mendapatkan hasil yang baik dari permintaan alami, yang tidak memiliki operator boolean seperti
strpos()
,preg_match()
,strstr()
ataustristr()
.NOTA BENE
Opsional menghilangkan redundansi sebelum mencari kata-kata
dengan demikian mengurangi ukuran indeks dan menghasilkan kebutuhan penyimpanan yang lebih sedikit
lebih sedikit disk I / O
pengindeksan lebih cepat dan pencarian yang lebih cepat akibatnya.
1. Normalisasi
2. Penghapusan stopword
3. Substitusi kamus
Ganti kata dengan yang lain yang memiliki arti identik atau serupa. (mis: ganti contoh 'lapar' dan 'lapar' dengan 'lapar')
Langkah-langkah algoritmik lebih lanjut (bola salju) dapat dilakukan untuk lebih mengurangi kata-kata menjadi arti penting mereka.
Penggantian nama warna dengan padanan heksadesimalnya
Pengurangan nilai numerik dengan mengurangi presisi adalah cara lain untuk menormalkan teks.
SUMBER DAYA
sumber
Jika Anda ingin menghindari masalah "falsey" dan "truthy", Anda dapat menggunakan substr_count:
Ini sedikit lebih lambat daripada tegar tetapi menghindari masalah perbandingan.
sumber
false
untuk "apakah Anda yakin?" karena posisistrpos
adalah0
Pilihan lain adalah menggunakan fungsi strstr () . Sesuatu seperti:
Poin yang perlu diperhatikan: Fungsi strstr () peka huruf besar-kecil. Untuk pencarian case-insensitive, gunakan fungsi stristr () .
sumber
sumber
WARNING preg_match(): Delimiter must not be alphanumeric or backslash
Saya agak terkesan bahwa tidak ada jawaban di sini yang digunakan
strpos
,strstr
dan fungsi yang serupa disebutkan Multibyte String Functions yet (2015-05-08).Pada dasarnya, jika Anda kesulitan menemukan kata-kata dengan karakter khusus untuk beberapa bahasa , seperti Jerman, Prancis, Portugis, Spanyol, dll. (Mis: ä , é , ô , ç , º , º , ñ ), Anda mungkin ingin mengawali fungsi dengan
mb_
. Oleh karena itu, jawaban yang diterima akan menggunakanmb_strpos
ataumb_stripos
(untuk pencocokan case-sensitive) sebagai gantinya:Jika Anda tidak dapat menjamin bahwa semua data Anda 100% di UTF-8 , Anda mungkin ingin menggunakan
mb_
fungsinya.Sebuah artikel yang bagus untuk memahami mengapa Minimum Yang Mutlak Setiap Pengembang Perangkat Lunak, Pasti Harus Tahu Tentang Unicode dan Karakter Set (Tanpa Alasan!) Oleh Joel Spolsky .
sumber
Di PHP, cara terbaik untuk memverifikasi apakah string berisi substring tertentu, adalah dengan menggunakan fungsi pembantu sederhana seperti ini:
Penjelasan:
strpos
menemukan posisi kemunculan pertama dari substring peka huruf besar-kecil dalam sebuah string.stripos
menemukan posisi kemunculan pertama substring yang tidak peka huruf besar-kecil dalam sebuah string.myFunction($haystack, $needle) === FALSE ? FALSE : TRUE
memastikan bahwamyFunction
selalu mengembalikan boolean dan memperbaiki perilaku tak terduga ketika indeks substring adalah 0.$caseSensitive ? A : B
memilih salah satustrpos
ataustripos
melakukan pekerjaan, tergantung pada nilai$caseSensitive
.Keluaran:
sumber
Fungsi di bawah ini juga berfungsi dan tidak bergantung pada fungsi lainnya; hanya menggunakan manipulasi string PHP asli. Secara pribadi, saya tidak merekomendasikan ini, tetapi Anda dapat melihat cara kerjanya:
Uji:
sumber
Anda dapat menggunakan
strstr
fungsi ini:Tanpa menggunakan fungsi bawaan:
sumber
Saya mengalami masalah dengan ini, dan akhirnya saya memilih untuk membuat solusi sendiri. Tanpa menggunakan mesin ekspresi reguler :
Anda mungkin memperhatikan bahwa solusi sebelumnya bukan jawaban untuk kata yang digunakan sebagai awalan untuk yang lain. Untuk menggunakan contoh Anda:
Dengan sampel di atas, keduanya
$a
dan$b
berisi$c
, tetapi Anda mungkin ingin fungsi Anda memberi tahu Anda bahwa hanya$a
berisi$c
.sumber
$found = false
di awalPilihan lain untuk menemukan kemunculan kata dari string menggunakan strstr () dan stristr () adalah seperti berikut:
sumber
i
instristr
adalah singkatan dari tidak sensitif.Banyak jawaban yang menggunakan
substr_count
pemeriksaan jika hasilnya>0
. Tetapi karenaif
pernyataan tersebut menganggap nol sama dengan false , Anda dapat menghindari cek itu dan menulis langsung:Untuk memeriksa apakah tidak ada, tambahkan
!
operator:sumber
Ini dapat dilakukan dengan tiga cara berbeda:
1- stristr ()
2- strpos ()
3- preg_match ()
sumber
Versi singkat
sumber
Untuk menemukan 'kata', daripada munculnya serangkaian huruf yang sebenarnya bisa menjadi bagian dari kata lain, berikut ini akan menjadi solusi yang baik.
sumber
$string
isAre are, are?
Anda harus menggunakan format case sensitif, jadi jika nilai yang dimasukkan dalam
small
ataucaps
tidak masalah.Di sini stripo menemukan jarum di heystack tanpa mempertimbangkan kasing (kecil / tutup).
Sampel PHPCode dengan output
sumber
Mungkin Anda bisa menggunakan sesuatu seperti ini:
sumber
Jangan gunakan
preg_match()
jika Anda hanya ingin memeriksa apakah satu string terkandung dalam string lain. Gunakanstrpos()
ataustrstr()
sebagai gantinya karena mereka akan lebih cepat. ( http://in2.php.net/preg_match )sumber
Jika Anda ingin memeriksa apakah string berisi beberapa kata spesifik, Anda dapat melakukan:
Ini berguna untuk menghindari spam saat mengirim email misalnya.
sumber
Fungsi strpos berfungsi dengan baik, tetapi jika Anda ingin
case-insensitive
memeriksa kata dalam sebuah paragraf maka Anda dapat menggunakanstripos
fungsiPHP
.Sebagai contoh,
Temukan posisi kemunculan pertama substring yang tidak peka huruf besar-kecil dalam string.
Jika kata itu tidak ada dalam string maka itu akan mengembalikan false kalau itu akan mengembalikan posisi kata.
sumber
Anda perlu menggunakan operator yang identik / tidak identik karena strpos dapat mengembalikan 0 sebagai nilai indeksnya. Jika Anda menyukai operator ternary, pertimbangkan untuk menggunakan yang berikut (sepertinya sedikit mundur saya akui):
sumber
Ini berarti string harus dipecahkan menjadi kata-kata (lihat catatan di bawah).
Salah satu cara untuk melakukan ini dan menentukan pemisah menggunakan
preg_split
( doc ):Berlari memberi
Catatan: Di sini kami tidak bermaksud kata untuk setiap urutan simbol.
Definisi praktis kata adalah dalam arti mesin ekspresi reguler PCRE, di mana kata-kata adalah substring yang hanya terdiri dari karakter kata, dipisahkan oleh karakter non-kata.
sumber
Solusi lain untuk string tertentu:
Anda juga dapat menggunakan
strpos()
fungsi.sumber