Відповіді:
Ви можете використовувати strpos()
функцію, яка використовується для пошуку виникнення однієї струни всередині іншої:
$a = 'How are you?';
if (strpos($a, 'are') !== false) {
echo 'true';
}
Зауважте, що використання препарату !== false
навмисне (ні це != false
не === true
поверне бажаного результату); strpos()
повертає або зсув, при якому голковий рядок починається в рядку сіна, або булевий, false
якщо голку не знайдено. Оскільки 0 - це дійсне зміщення, а 0 - "фальси", ми не можемо використовувати більш прості конструкції, як-от !strpos($a, 'are')
.
strpos($a, 'are') > -1
для перевірки на справжність. З точки зору налагодження я вважаю, що мій мозок витрачає меншу кількість тактових циклів, визначаючи, чи правильно написано рядок, коли мені не потрібно рахувати суміжні знаки рівності.
Ви можете використовувати регулярні вирази, це краще для відповідності слів порівняно з тим, strpos
як згадували інші користувачі, воно також поверне істинне для рядків, таких як тариф, догляд, погляд тощо. Цього просто можна уникнути в регулярному вираженні, використовуючи межі слів.
Простий матч для are може виглядати приблизно так:
$a = 'How are you?';
if (preg_match('/\bare\b/', $a)) {
echo 'true';
}
Що стосується продуктивності, strpos
це приблизно втричі швидше, і майте на увазі, коли я зробив один мільйон порівнянь одразу, на це пішло preg_match
1,5 секунди, і на strpos
це пішло 0,5 секунди.
Редагувати: Щоб шукати будь-яку частину рядка, а не лише слово за словом, я рекомендую використовувати звичайний вираз, як-от
$a = 'How are you?';
$search = 'are y';
if(preg_match("/{$search}/i", $a)) {
echo 'true';
}
В i
кінці регулярного вираження змінюється регулярний вираз, щоб він не залежав від регістру, якщо ви цього не хочете, можете залишити його.
Тепер це може бути досить проблематично, оскільки рядок пошуку $ не захищено жодним чином, я маю на увазі, він може не пройти перевірку в деяких випадках, як якщо б $search
це введення користувача, вони можуть додати рядок, який може вести себе як якийсь різний регулярний вираз ...
Також ось чудовий інструмент для тестування та перегляду пояснень різних регулярних виразів Regex101
Щоб поєднати обидва набори функціональності в одній багатоцільовій функції (в тому числі і з можливістю вибору регістру), ви можете використовувати щось подібне:
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.
}
Ось невелика корисна функція, яка корисна в таких ситуаціях
// returns true if $needle is a substring of $haystack
function contains($needle, $haystack)
{
return strpos($haystack, $needle) !== false;
}
if ($email->contains("@") && $email->endsWith(".com)) { ...
абоif (strpos($email, "@") !== false && substr($email, -strlen(".com")) == ".com") { ...
Хоча більшість цих відповідей підкаже, якщо підрядка з’являється у вашому рядку, зазвичай це не те, що потрібно, якщо ви шукаєте певне слово , а не підрядку .
Яка різниця? Підрядки можуть з’являтися в межах інших слів:
Одним із способів пом'якшити це було б використовувати регулярний вираз у поєднанні зі межами слова ( \b
):
function containsWord($str, $word)
{
return !!preg_match('#\\b' . preg_quote($word, '#') . '\\b#i', $str);
}
Цей метод не має тих самих помилкових позитивів, як зазначено вище, але він має окремі кращі випадки. Межі слова збігаються з символами без слів ( \W
), які збираються бути нічого , що ні a-z
, A-Z
, 0-9
або _
. Це означає, що цифри та підкреслення будуть зараховані до символів слова та сценаріїв, подібних до цього, не вдасться:
Якщо ви хочете щось більш точне, ніж це, вам доведеться почати робити синтаксичний розбір синтаксису в англійській мові, і це досить велика банка глистів (і при будь-якому випадку передбачає правильне використання синтаксису, як це не завжди).
\b
відповідає двом речам, що \W
не відповідає, що робить його чудовим для пошуку слів у рядку: Він відповідає початку рядка ( ^
) та кінця рядка ( $
)
Щоб визначити, чи містить рядок іншу рядок, можна використовувати функцію PHP 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";
}
?>
ОБЕРЕЖНО:
Якщо голка, яку ви шукаєте, знаходиться на початку стога сіна, вона поверне позицію 0, якщо ви зробите ==
порівняння, яке не буде працювати, вам потрібно буде зробити===
==
Знак порівняння і тести , чи має змінні / вираз / постійні вліво таке ж значення , як змінні / вираз / константу справа.
===
Знак порівняння , щоб побачити чи дві змінні / постійні / як вирази дорівнюють AND
мають однаковий тип - тобто обидва рядки або обидва є цілими числами.
<?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.";
}
?>
strstr($a, 'are')
набагато елегантніше, ніж потворне strpos($a, 'are') !== false
. PHP дійсно потребує str_contains()
функції.
Використовуйте відповідність між регістром та регістром за допомогою stripos()
:
if (stripos($string,$stringToSearch) !== false) {
echo 'true';
}
Коментарі до коментарів SamGoody та Lego Stormtroopr.
Якщо ви шукаєте алгоритм PHP для ранжування результатів пошуку на основі близькості / релевантності декількох слів, тут з'являється швидкий і простий спосіб генерування результатів пошуку лише за допомогою PHP:
Проблеми , пов'язані з іншими методами булева пошуку , такі як strpos()
, preg_match()
, strstr()
абоstristr()
PHP-метод, заснований на векторній космічній моделі та tf-idf (термін частота-обернена частота документа):
Це звучить важко, але напрочуд легко.
Якщо ми хочемо шукати кілька слів у рядку, основною проблемою є те, як ми присвоюємо вагу кожному з них?
Якби ми могли зважити терміни в рядку, виходячи з того, наскільки вони репрезентативні для рядка в цілому, ми могли б замовити наші результати за тими, які найкраще відповідають запиту.
Це ідея векторної космічної моделі, недалеко від того, як працює повнотекстовий пошук SQL:
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;
}
СЛУЧАЙ 1
$query = 'are';
$corpus = array(
1 => 'How are you?',
);
$match_results=get_similar_documents($query,$corpus);
echo '<pre>';
print_r($match_results);
echo '</pre>';
РЕЗУЛЬТАТ
Array
(
[1] => 0.52832083357372
)
СЛУЧАЙ 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>';
РЕЗУЛЬТАТИ
Array
(
[1] => 0.54248125036058
[3] => 0.21699250014423
)
СЛУЧАЙ 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>';
РЕЗУЛЬТАТИ
Array
(
[3] => 0.6813781191217
[1] => 0.54248125036058
)
Є багато покращень , які будуть зроблені , але модель забезпечує спосіб отримання результатів хороших з природних запитів, які не мають логічних операторів , таких як strpos()
, preg_match()
, strstr()
або stristr()
.
NOTA BENE
Необов'язково усунення надмірності до пошуку слів
тим самим зменшуючи розмір індексу і призводячи до меншої потреби в зберіганні
менше дискового вводу / виводу
швидше індексування і, отже, швидший пошук.
1. Нормалізація
2. Видалення стоп-слова
3. Підстановка словника
Замініть слова іншими, які мають однакове або подібне значення. (наприклад: замініть випадки "голодно" та "голодних" на "голод")
Подальші алгоритмічні заходи (снігова куля) можуть бути виконані для подальшого зменшення слів до їх істотного значення.
Заміна назв кольорів їх шістнадцятковими еквівалентами
Зменшення числових значень шляхом зменшення точності - це інші способи нормалізації тексту.
РЕСУРСИ
Якщо ви хочете уникнути проблеми "фальси" та "тризуби", можете скористатися substr_count:
if (substr_count($a, 'are') > 0) {
echo "at least one 'are' is present!";
}
Це трохи повільніше, ніж strpos, але це уникає проблем зі порівнянням.
false
для "Ви впевнені?" так як положення на strpos
це0
Іншим варіантом є використання функції strstr () . Щось на зразок:
if (strlen(strstr($haystack,$needle))>0) {
// Needle Found
}
Зауважте: Функція strstr () відрізняється від регістру. Для нечутливого до регістру пошуку використовуйте функцію stristr () .
Мене трохи вразило, що жодна з відповідей, що використовувались strpos
, strstr
та подібні функції ще не згадували багатобайтові струнні функції (2015-05-08)
В основному, якщо у вас виникають проблеми з пошуком слів із символами, характерними для деяких мов , наприклад, німецької, французької, португальської, іспанської тощо (наприклад: ä , é , ô , ç , º , ñ ), можливо, ви захочете передувати функції з mb_
. Тому прийнята відповідь використовує mb_strpos
або mb_stripos
(для невідповідності регістру) натомість:
if (mb_strpos($a,'are') !== false) {
echo 'true';
}
Якщо ви не можете гарантувати, що всі ваші дані на UTF-8 на 100% , ви можете скористатись mb_
функціями.
Хороша стаття , щоб зрозуміти , чому це абсолютний мінімум кожен розробник програмного забезпечення Абсолютно позитивно повинні знати про Unicode і наборів символів , (НЕ відмовки!) По Джоел Спольскі .
У PHP найкращий спосіб перевірити, чи містить рядок певну підрядку, - це використовувати просту функцію помічника, як це:
function contains($haystack, $needle, $caseSensitive = false) {
return $caseSensitive ?
(strpos($haystack, $needle) === FALSE ? FALSE : TRUE):
(stripos($haystack, $needle) === FALSE ? FALSE : TRUE);
}
strpos
знаходить позицію першого виникнення чутливої до регістру підрядки в рядку.stripos
знаходить позицію першого виникнення нечутливої до регістру підрядки в рядку.myFunction($haystack, $needle) === FALSE ? FALSE : TRUE
гарантує, що myFunction
завжди повертає булеве значення і виправляє несподівану поведінку, коли індекс підрядки дорівнює 0.$caseSensitive ? A : B
вибирає strpos
або stripos
виконувати роботу, залежно від значення $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)
Функція нижче також працює і не залежить від будь-якої іншої функції; він використовує лише натисну маніпуляцію PHP-рядком. Особисто я не рекомендую цього, але ви можете побачити, як це працює:
<?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;
}
}
Тест:
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
Ви можете використовувати strstr
функцію:
$haystack = "I know programming";
$needle = "know";
$flag = strstr($haystack, $needle);
if ($flag){
echo "true";
}
Без використання вбудованої функції:
$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 ";
}
У мене були проблеми з цим, і нарешті я вирішив створити власне рішення. Без використання механізму регулярного вираження :
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;
}
Ви можете помітити, що попередні рішення - це не відповідь на слово, яке використовується як префікс іншого. Для того, щоб використовувати ваш приклад:
$a = 'How are you?';
$b = "a skirt that flares from the waist";
$c = "are";
З прикладами, наведеними вище, $a
і $b
містяться $c
, але ви, можливо, хочете, щоб ваша функція розповідала, що $a
містить лише $c
.
$found = false
на увазі: на початку
Інший варіант пошуку слова з рядка за допомогою strstr () та stristr () - такий:
<?php
$a = 'How are you?';
if (strstr($a,'are')) // Case sensitive
echo 'true';
if (stristr($a,'are')) // Case insensitive
echo 'true';
?>
i
В stristr
означає нечутливі.
Дуже багато відповідей, які використовують substr_count
перевірки, якщо результат є >0
. Але оскільки if
твердження вважає нуль таким же, як хибне , ви можете уникнути цієї перевірки та записати безпосередньо:
if (substr_count($a, 'are')) {
Щоб перевірити, чи немає , додайте !
оператора:
if (!substr_count($a, 'are')) {
Це можна зробити трьома різними способами:
$a = 'How are you?';
1- stristr ()
if (strlen(stristr($a,"are"))>0) {
echo "true"; // are Found
}
2- стріпос ()
if (strpos($a, "are") !== false) {
echo "true"; // are Found
}
3- preg_match ()
if( preg_match("are",$a) === 1) {
echo "true"; // are Found
}
Версія з короткою рукою
$result = false!==strpos($a, 'are');
Для того, щоб знайти «слово», а не виникнути ряд букв, які насправді можуть бути частиною іншого слова, наступне було б хорошим рішенням.
$string = 'How are you?';
$array = explode(" ", $string);
if (in_array('are', $array) ) {
echo 'Found the word';
}
$string
єAre are, are?
Ви повинні використовувати формат Insensitive, якщо введене значення є small
або caps
воно не має значення.
<?php
$grass = "This is pratik joshi";
$needle = "pratik";
if (stripos($grass,$needle) !== false) {
/*If i EXCLUDE : !== false then if string is found at 0th location,
still it will say STRING NOT FOUND as it will return '0' and it
will goto else and will say NOT Found though it is found at 0th location.*/
echo 'Contains word';
}else{
echo "does NOT contain word";
}
?>
Тут стрипос знаходить голку в копиці сіна, не враховуючи корпусу (маленький / кришки).
Можливо, ви могли б використовувати щось подібне:
<?php
findWord('Test all OK');
function findWord($text) {
if (strstr($text, 'ok')) {
echo 'Found a word';
}
else
{
echo 'Did not find a word';
}
}
?>
Не використовуйте, preg_match()
якщо ви хочете перевірити, чи міститься одна струна в іншій. Використовуйте strpos()
або strstr()
замість цього вони будуть швидшими. ( http://in2.php.net/preg_match )
if (strpos($text, 'string_name') !== false){
echo 'get the string';
}
Якщо ви хочете перевірити, чи містить рядок кілька слів конкретики, ви можете зробити:
$badWords = array("dette", "capitale", "rembourser", "ivoire", "mandat");
$string = "a string with the word ivoire";
$matchFound = preg_match_all("/\b(" . implode($badWords,"|") . ")\b/i", $string, $matches);
if ($matchFound) {
echo "a bad word has been found";
}
else {
echo "your string is okay";
}
Це корисно, щоб уникнути спаму, наприклад, надсилаючи електронні листи.
Функція strpos працює чудово, але якщо ви хочете case-insensitive
перевірити слово в абзаці, ви можете скористатися stripos
функцією PHP
.
Наприклад,
$result = stripos("I love PHP, I love PHP too!", "php");
if ($result === false) {
// Word does not exist
}
else {
// Word exists
}
Знайдіть позицію першого виникнення нечутливої до регістру підрядки в рядку.
Якщо слова не існує в рядку, воно поверне помилкове, воно поверне позицію слова.
Вам потрібно використовувати однакові / не ідентичні оператори, тому що strpos може повертати 0 як значення індексу. Якщо вам подобаються потрійні оператори, подумайте про те, щоб скористатись цим (здається, трохи назад, я визнаю):
echo FALSE === strpos($a,'are') ? 'false': 'true';
Перевірте, чи містить рядок конкретні слова?
Це означає, що рядок має бути розв'язаний словами (див. Примітку нижче).
Один із способів зробити це і вказати роздільники: preg_split
( doc ):
<?php
function contains_word($str, $word) {
// split string into words
// separators are substrings of at least one non-word character
$arr = preg_split('/\W+/', $str, NULL, PREG_SPLIT_NO_EMPTY);
// now the words can be examined each
foreach ($arr as $value) {
if ($value === $word) {
return true;
}
}
return false;
}
function test($str, $word) {
if (contains_word($str, $word)) {
echo "string '" . $str . "' contains word '" . $word . "'\n";
} else {
echo "string '" . $str . "' does not contain word '" . $word . "'\n" ;
}
}
$a = 'How are you?';
test($a, 'are');
test($a, 'ar');
test($a, 'hare');
?>
Пробіг дає
$ php -f test.php
string 'How are you?' contains word 'are'
string 'How are you?' does not contain word 'ar'
string 'How are you?' does not contain word 'hare'
Примітка. Тут ми не маємо на увазі слово для кожної послідовності символів.
Практичне визначення слова - це сенс механізму регулярного вираження PCRE, де слова - це підрядки, що складаються лише з символів слова, відокремлених несловними символами.
Символ "слова" - це будь-яка літера або цифра або символ підкреслення, тобто будь-який символ, який може бути частиною слова "Perl". Визначення букв і цифр контролюється таблицями символів PCRE і може змінюватись, якщо відбувається відповідність для локальної мови (..)