Рассматривать:
$a = 'How are you?';
if ($a contains 'are')
echo 'true';
Предположим, у меня есть код выше, как правильно написать заявление if ($a contains 'are')
?
Рассматривать:
$a = 'How are you?';
if ($a contains 'are')
echo 'true';
Предположим, у меня есть код выше, как правильно написать заявление if ($a contains 'are')
?
Ответы:
Вы можете использовать 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
что было упомянуто другими пользователями, он также будет возвращать true для таких строк, как стоимость, уход, взгляд и т. Д. Этого можно просто избежать в регулярном выражении, используя границы слов.
Простое совпадение для может выглядеть примерно так:
$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
не соответствуют, что делает его отличным для поиска слов в строке: Это соответствует началу string ( ^
) и концу string ( $
)
Чтобы определить, содержит ли строка другую строку, вы можете использовать функцию 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()
или, stristr()
если ваш поиск должен быть без учета регистра, было бы другим вариантом.
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()
.
НОТА БЕНЕ
Опционально устранение избыточности перед поиском по словам
тем самым уменьшая размер индекса и приводя к меньшему требованию к памяти
меньше дискового ввода / вывода
более быстрая индексация и, следовательно, более быстрый поиск.
1. Нормализация
2. Устранение стоп-слов
3. Подстановка словаря
Замените слова другими словами, которые имеют одинаковое или похожее значение. (например: заменить «голодный» и «голодный» на «голодный»)
Дальнейшие алгоритмические меры (снежный ком) могут быть выполнены для дальнейшего приведения слов к их существенному значению.
Замена имен цветов их шестнадцатеричными эквивалентами
Сокращение числовых значений за счет снижения точности являются другими способами нормализации текста.
РЕСУРСЫ
Если вы хотите избежать проблем "falsey" и "truey", вы можете использовать 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';
}
Если вы не можете гарантировать, что все ваши данные на 100% в UTF-8 , вы можете использовать эти 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-стристр ()
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
}
Сокращенная версия
$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?
Вы должны использовать регистр без учета регистра, поэтому, если введенное значение соответствует 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
}
Найти позицию первого вхождения нечувствительной к регистру подстроки в строке.
Если слово не существует в строке, оно вернет false, иначе вернет позицию слова.
Вам нужно использовать идентичные / не идентичные операторы, потому что 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 и может отличаться, если происходит сопоставление для конкретной локали (..)