Pertimbangkan:
$a = 'How are you?';
if ($a contains 'are')
echo 'true';
Misalkan saya punya kode di atas, apa cara yang benar untuk menulis pernyataan jika ($a berisi 'yang')
?
Anda dapat menggunakan strpos()
fungsi yang digunakan untuk menemukan terjadinya suatu string di dalam satu sama lain:
$a = 'How are you?';
if (strpos($a, 'are') !== false) {
echo 'true';
}
Perhatikan bahwa penggunaan !== palsu
adalah disengaja (tidak != palsu
atau === sejati
akan kembali hasil yang diinginkan); strpos()
kembali baik offset di mana jarum string dimulai di tumpukan jerami string atau boolean palsu
jika jarum isn't menemukan. Karena 0 adalah valid offset dan 0 adalah "falsey", kita bisa't menggunakan konstruksi sederhana seperti !strpos($a, 'yang')
.
Anda dapat menggunakan ekspresi reguler, it's baik untuk pencocokan kata dibandingkan dengan strpos
seperti yang disebutkan oleh pengguna lain hal ini juga akan kembali berlaku untuk string seperti tarif, perawatan, menatap, dll. Ini hanya dapat dihindari dalam ekspresi regular dengan menggunakan batas kata.
Sederhana cocok bagi yang bisa melihat sesuatu seperti ini:
$a = 'How are you?';
if (preg_match('/\bare\b/', $a)) {
echo 'true';
}
Pada sisi kinerja, strpos
adalah sekitar tiga kali lebih cepat dan memiliki dalam pikiran, ketika saya melakukan satu juta membandingkan sekaligus, butuh preg_match
1,5 detik untuk menyelesaikan dan untuk strpos
butuh waktu 0,5 detik.
Edit: Dalam rangka untuk mencari setiap bagian dari string, tidak hanya kata demi kata, saya akan merekomendasikan menggunakan ekspresi reguler seperti
$a = 'How are you?';
$search = 'are y';
if(preg_match("/{$search}/i", $a)) {
echo 'true';
}
I
pada akhir dari ekspresi reguler perubahan ekspresi reguler untuk kasus-sensitif, jika anda tidak ingin ini, anda dapat meninggalkan itu.
Sekarang, hal ini dapat menjadi cukup bermasalah dalam beberapa kasus sebagai $string pencarian isn't dibersihkan dengan cara apapun, maksud saya, mungkin tidak lulus cek di beberapa kasus seolah-olah $cari
adalah user input mereka dapat menambahkan beberapa string yang mungkin berperilaku seperti beberapa yang berbeda ekspresi reguler...
Juga, di sini's alat yang hebat untuk menguji dan melihat penjelasan dari berbagai ekspresi reguler Regex101
Untuk menggabungkan kedua set fungsi menjadi satu multi-tujuan fungsi (termasuk dengan dipilih sensitivitas kasus), anda bisa menggunakan sesuatu seperti ini:
function FindString($needle,$haystack,$i,$word)
{ // $i should be "" or "i" for case insensitive
if (strtoupper($word)=="W")
{ // if $word is "W" then word search instead of string in string search.
if (preg_match("/\b{$needle}\b/{$i}", $haystack))
{
return true;
}
}
else
{
if(preg_match("/{$needle}/{$i}", $haystack))
{
return true;
}
}
return false;
// Put quotes around true and false above to return them as strings instead of as bools/ints.
}
Sementara sebagian besar dari jawaban-jawaban ini akan memberitahu anda jika substring muncul dalam string, yang's biasanya bukan apa yang anda inginkan jika anda'kembali mencari tertentu word, dan substring.
Apa's perbedaan? Substring dapat muncul dalam kata lain:
Salah satu cara untuk mengurangi ini akan menggunakan ekspresi reguler ditambah dengan kata-batas (\b
):
function containsWord($str, $word)
{
return !!preg_match('#\\b' . preg_quote($word, '#') . '\\b#i', $str);
}
Metode ini doesn't sama-sama positif palsu yang disebutkan di atas, tetapi memiliki beberapa kasus tepi sendiri. Kata-batas pada pertandingan non-karakter kata (\W
), yang akan menjadi sesuatu yang isn't a-z
, A-Z
, 0-9
, atau _
. Itu berarti angka dan garis bawah akan dihitung sebagai karakter kata dan skenario seperti ini akan gagal:
Jika anda ingin sesuatu yang lebih akurat dari ini, anda'll harus mulai melakukan bahasa inggris sintaks parsing, dan yang's yang cukup besar dapat cacing (dan mengasumsikan penggunaan yang tepat dari sintaks, sih, yang isn't selalu diberikan).
Untuk menentukan apakah sebuah string berisi string lain anda dapat menggunakan fungsi PHP strpos().
int strpos ( string $jerami , dicampur $jarum [, int $offset = 0 ] )
<?php
$haystack = 'how are you';
$needle = 'are';
if (strpos($haystack,$needle) !== false) {
echo "$haystack contains $needle";
}
?>
Hati-HATI:
Jika jarum anda sedang mencari di awal tumpukan jerami itu akan kembali ke posisi 0, jika anda melakukan ==
dibandingkan yang tidak akan bekerja, anda akan perlu untuk melakukan ===
A ==
tanda ini adalah perbandingan dan pengujian apakah variabel / ekspresi / konstan ke kiri memiliki nilai yang sama sebagai variabel / ekspresi / konstan ke kanan.
A ===
tanda pembanding untuk melihat apakah dua variabel / expresions / konstanta yang sama DAN
memiliki tipe yang sama yaitu kedua adalah string atau keduanya adalah bilangan bulat.
<?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.";
}
?>
Peer to SamGoody dan Lego Stormtroopr komentar.
Jika anda mencari untuk PHP algoritma untuk urutkan hasil pencarian berdasarkan kedekatan/relevansi beberapa kata-kata inilah cara cepat dan mudah menghasilkan hasil pencarian dengan PHP saja:
Masalah dengan lain pencarian boolean metode seperti strpos()
, preg_match()
, strstr()
atau stristr()
PHP metode yang didasarkan pada Vector Space Model dan tf-idf (term frequency–inverse document frequency):
Kedengarannya sulit, tapi adalah mengherankan mudah.
Jika kita ingin mencari beberapa kata dalam string inti masalah adalah bagaimana kita menetapkan bobot untuk setiap salah satu dari mereka?
Jika kita bisa berat syarat-syarat dalam sebuah string berdasarkan bagaimana perwakilan mereka dari string secara keseluruhan, kita bisa memesan hasil kami dengan orang-orang yang terbaik sesuai dengan permintaan.
Ini adalah ide vector space model, tidak jauh dari bagaimana SQL pencarian teks lengkap karya:
function get_corpus_index($corpus = array(), $separator=' ') {
$dictionary = array();
$doc_count = array();
foreach($corpus as $doc_id => $doc) {
$terms = explode($separator, $doc);
$doc_count[$doc_id] = count($terms);
// tf–idf, short for term frequency–inverse document frequency,
// according to wikipedia is a numerical statistic that is intended to reflect
// how important a word is to a document in a corpus
foreach($terms as $term) {
if(!isset($dictionary[$term])) {
$dictionary[$term] = array('document_frequency' => 0, 'postings' => array());
}
if(!isset($dictionary[$term]['postings'][$doc_id])) {
$dictionary[$term]['document_frequency']++;
$dictionary[$term]['postings'][$doc_id] = array('term_frequency' => 0);
}
$dictionary[$term]['postings'][$doc_id]['term_frequency']++;
}
//from http://phpir.com/simple-search-the-vector-space-model/
}
return array('doc_count' => $doc_count, 'dictionary' => $dictionary);
}
function get_similar_documents($query='', $corpus=array(), $separator=' '){
$similar_documents=array();
if($query!=''&&!empty($corpus)){
$words=explode($separator,$query);
$corpus=get_corpus_index($corpus, $separator);
$doc_count=count($corpus['doc_count']);
foreach($words as $word) {
if(isset($corpus['dictionary'][$word])){
$entry = $corpus['dictionary'][$word];
foreach($entry['postings'] as $doc_id => $posting) {
//get term frequency–inverse document frequency
$score=$posting['term_frequency'] * log($doc_count + 1 / $entry['document_frequency'] + 1, 2);
if(isset($similar_documents[$doc_id])){
$similar_documents[$doc_id]+=$score;
}
else{
$similar_documents[$doc_id]=$score;
}
}
}
}
// length normalise
foreach($similar_documents as $doc_id => $score) {
$similar_documents[$doc_id] = $score/$corpus['doc_count'][$doc_id];
}
// sort from high to low
arsort($similar_documents);
}
return $similar_documents;
}
KASUS 1
$query = 'are';
$corpus = array(
1 => 'How are you?',
);
$match_results=get_similar_documents($query,$corpus);
echo '<pre>';
print_r($match_results);
echo '</pre>';
HASIL
Array
(
[1] => 0.52832083357372
)
KASUS 2
$query = 'are';
$corpus = array(
1 => 'how are you today?',
2 => 'how do you do',
3 => 'here you are! how are you? Are we done yet?'
);
$match_results=get_similar_documents($query,$corpus);
echo '<pre>';
print_r($match_results);
echo '</pre>';
HASIL
Array
(
[1] => 0.54248125036058
[3] => 0.21699250014423
)
KASUS 3
$query = 'we are done';
$corpus = array(
1 => 'how are you today?',
2 => 'how do you do',
3 => 'here you are! how are you? Are we done yet?'
);
$match_results=get_similar_documents($query,$corpus);
echo '<pre>';
print_r($match_results);
echo '</pre>';
HASIL
Array
(
[3] => 0.6813781191217
[1] => 0.54248125036058
)
Ada banyak perbaikan yang harus dilakukan
tapi model ini menyediakan cara untuk mendapatkan hasil yang baik dari alam query,
yang don't memiliki operator boolean seperti strpos()
, preg_match()
, strstr()
atau stristr()
.
NOTA BENE
Opsional menghilangkan redundansi sebelum mencari kata-kata
sehingga mengurangi ukuran indeks dan mengakibatkan penyimpanan kurang syarat
kurang disk I/O
mengindeks lebih cepat dan akibatnya pencarian yang lebih cepat.
1. Normalisasi
2. Penghapusan Stopword
3. Kamus substitusi
Ganti kata-kata dengan orang lain yang memiliki yang sama atau serupa maknanya. (ex:ganti contoh 'lapar' dan 'lapar' dengan 'hunger')
Selanjutnya algoritma langkah-langkah (snowball) dapat dilakukan untuk mengurangi kata-kata untuk mereka arti penting.
Penggantian warna nama-nama mereka heksadesimal setara
Pengurangan dari nilai-nilai numerik dengan mengurangi presisi adalah cara lain dari normalisasi teks.
Sumber DAYA
Jika anda ingin menghindari "falsey" dan "truthy" masalah, anda dapat menggunakan substr_count:
if (substr_count($a, 'are') > 0) {
echo "at least one 'are' is present!";
}
It's sedikit lebih lambat dari strpos tapi menghindari perbandingan masalah.
I'm sedikit terkesan bahwa tidak satupun dari jawaban berikut yang digunakan strpos
, strstr
dan fungsi yang sama disebutkan Multibyte String Fungsi namun (2015-05-08).
Pada dasarnya, jika anda're kesulitan mencari kata-kata dengan karakter tertentu untuk beberapa bahasa, seperti jerman, perancis, portugis, spanyol, dll. (mis.: ä, é, ô, ç, º, ñ), anda mungkin ingin mendahului fungsi dengan mb_
. Oleh karena itu, jawaban yang diterima akan menggunakan mb_strpos
atau mb_stripos
(untuk kasus-sensitif matching) sebagai gantinya:
if (mb_strpos($a,'are') !== false) {
echo 'true';
}
Jika anda tidak dapat menjamin bahwa semua data anda 100% dalam UTF-8, anda mungkin ingin menggunakan mb_
fungsi.
Sebuah artikel yang baik untuk memahami mengapa Minimum Absolut Setiap Pengembang perangkat Lunak benar-Benar, Positif Harus Tahu Tentang Unicode dan Set Karakter (Tidak ada Alasan!) oleh Joel Spolsky.
Di PHP, cara terbaik untuk memverifikasi apakah sebuah string yang berisi substring tertentu, adalah dengan menggunakan sederhana helper fungsi seperti ini:
function contains($haystack, $needle, $caseSensitive = false) {
return $caseSensitive ?
(strpos($haystack, $needle) === FALSE ? FALSE : TRUE):
(stripos($haystack, $needle) === FALSE ? FALSE : TRUE);
}
strpos
menemukan posisi pertama terjadinya kasus-sensitif substring dalam suatu string.stripos
menemukan posisi pertama terjadinya kasus-sensitif substring dalam suatu string.myFunction($jerami, $jarum) === FALSE ? FALSE : TRUE
memastikan myFunction
selalu mengembalikan boolean dan perbaikan perilaku tak terduga ketika indeks substring adalah 0.$caseSensitive ? A : B
memilih strpos
atau stripos
untuk melakukan pekerjaan, tergantung pada nilai dari $caseSensitive
.var_dump(contains('bare','are')); // Outputs: bool(true)
var_dump(contains('stare', 'are')); // Outputs: bool(true)
var_dump(contains('stare', 'Are')); // Outputs: bool(true)
var_dump(contains('stare', 'Are', true)); // Outputs: bool(false)
var_dump(contains('hair', 'are')); // Outputs: bool(false)
var_dump(contains('aren\'t', 'are')); // Outputs: bool(true)
var_dump(contains('Aren\'t', 'are')); // Outputs: bool(true)
var_dump(contains('Aren\'t', 'are', true)); // Outputs: bool(false)
var_dump(contains('aren\'t', 'Are')); // Outputs: bool(true)
var_dump(contains('aren\'t', 'Are', true)); // Outputs: bool(false)
var_dump(contains('broad', 'are')); // Outputs: bool(false)
var_dump(contains('border', 'are')); // Outputs: bool(false)
Fungsi di bawah ini juga bekerja dan tidak bergantung pada fungsi yang lain; ia hanya menggunakan native PHP manipulasi string. Secara pribadi, saya tidak merekomendasikan hal ini, tetapi anda dapat melihat bagaimana hal itu bekerja:
<?php
if (!function_exists('is_str_contain')) {
function is_str_contain($string, $keyword)
{
if (empty($string) || empty($keyword)) return false;
$keyword_first_char = $keyword[0];
$keyword_length = strlen($keyword);
$string_length = strlen($string);
// case 1
if ($string_length < $keyword_length) return false;
// case 2
if ($string_length == $keyword_length) {
if ($string == $keyword) return true;
else return false;
}
// case 3
if ($keyword_length == 1) {
for ($i = 0; $i < $string_length; $i++) {
// Check if keyword's first char == string's first char
if ($keyword_first_char == $string[$i]) {
return true;
}
}
}
// case 4
if ($keyword_length > 1) {
for ($i = 0; $i < $string_length; $i++) {
/*
the remaining part of the string is equal or greater than the keyword
*/
if (($string_length + 1 - $i) >= $keyword_length) {
// Check if keyword's first char == string's first char
if ($keyword_first_char == $string[$i]) {
$match = 1;
for ($j = 1; $j < $keyword_length; $j++) {
if (($i + $j < $string_length) && $keyword[$j] == $string[$i + $j]) {
$match++;
}
else {
return false;
}
}
if ($match == $keyword_length) {
return true;
}
// end if first match found
}
// end if remaining part
}
else {
return false;
}
// end for loop
}
// end case4
}
return false;
}
}
Tes:
var_dump(is_str_contain("test", "t")); //true
var_dump(is_str_contain("test", "")); //false
var_dump(is_str_contain("test", "test")); //true
var_dump(is_str_contain("test", "testa")); //flase
var_dump(is_str_contain("a----z", "a")); //true
var_dump(is_str_contain("a----z", "z")); //true
var_dump(is_str_contain("mystringss", "strings")); //true
Anda dapat menggunakan strstr
fungsi:
$haystack = "I know programming";
$needle = "know";
$flag = strstr($haystack, $needle);
if ($flag){
echo "true";
}
Tanpa menggunakan built-in fungsi:
$haystack = "hello world";
$needle = "llo";
$i = $j = 0;
while (isset($needle[$i])) {
while (isset($haystack[$j]) && ($needle[$i] != $haystack[$j])) {
$j++;
$i = 0;
}
if (!isset($haystack[$j])) {
break;
}
$i++;
$j++;
}
if (!isset($needle[$i])) {
echo "YES";
}
else{
echo "NO ";
}
Aku punya beberapa masalah dengan hal ini, dan akhirnya saya memilih untuk membuat sendiri larutan. Tanpa menggunakan ekspresi mesin:
function contains($text, $word)
{
$found = false;
$spaceArray = explode(' ', $text);
$nonBreakingSpaceArray = explode(chr(160), $text);
if (in_array($word, $spaceArray) ||
in_array($word, $nonBreakingSpaceArray)
) {
$found = true;
}
return $found;
}
Anda mungkin memperhatikan bahwa solusi yang sebelumnya tidak jawaban untuk kata yang digunakan sebagai awalan untuk yang lain. Dalam rangka untuk menggunakan anda contoh:
$a = 'How are you?';
$b = "a skirt that flares from the waist";
$c = "are";
Dengan contoh di atas, kedua $a
dan $b
berisi $c
, tapi mungkin anda ingin fungsi untuk memberitahu anda bahwa hanya $a
berisi $c
.
Banyak jawaban yang menggunakan substr_count
cek jika hasilnya >0
. Tapi sejak jika
pernyataan yang menganggap nol sama seperti palsu, anda dapat menghindari yang memeriksa dan menulis langsung:
if (substr_count($a, 'are')) {
Untuk memeriksa apakah not hadir, tambahkan !
operator:
if (!substr_count($a, 'are')) {
Hal ini dapat dilakukan dalam tiga cara yang berbeda:
$a = 'How are you?';
1 - stristr()
if (strlen(stristr($a,"are"))>0) {
echo "true"; // are Found
}
2 - strpos()
if (strpos($a, "are") !== false) {
echo "true"; // are Found
}
3 - preg_match()
if( preg_match("are",$a) === 1) {
echo "true"; // are Found
}