Рассматривать:
$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
является преднамеренным; strpos()
возвращает либо смещение, при котором игольная строка начинается в строке стога сена, либо логическое значение false
если игла не найдена. Поскольку 0 является допустимым смещением и 0 является «ложным», мы не можем использовать более простые конструкции, такие как !strpos($a, 'are')
.
Вы можете использовать регулярные выражения, лучше для сопоставления слов по сравнению с strpos, как упомянуто другими пользователями, он также вернет true для строк, таких как тариф, уход, stare и т. Д. Этого можно просто избежать в регулярном выражении, используя границы слов.
Простой матч для них может выглядеть примерно так:
$a = 'How are you?';
if (preg_match('/\bare\b/',$a))
echo 'true';
С точки зрения производительности, strpos примерно в три раза быстрее и имеет в виду, когда я делал один миллион сравнений сразу, для завершения игры потребовалось 1,5 секунды, а для strpos - 0,5 секунды.
Вот небольшая полезная функция, которая полезна в таких ситуациях
// returns true if $needle is a substring of $haystack
function contains($needle, $haystack)
{
return strpos($haystack, $needle) !== false;
}
Хотя большинство этих ответов скажут вам, есть ли подстрока в вашей строке, это обычно не то, что вы хотите, если ищете определенное слово , а не подстроку .
Какая разница? Подстроки могут появляться иными словами:
Одним из способов смягчения этого было бы использовать регулярное выражение в сочетании со слоями ( \b
):
function containsWord($str, $word)
{
return !!preg_match('#\\b' . preg_quote($word, '#') . '\\b#i', $str);
}
Этот метод не имеет тех же ложных срабатываний, которые были отмечены выше, но у него есть некоторые краевые случаи. Границы слов совпадают с символами без слов ( \W
), которые будут не такими, как a-z
, A-Z
, 0-9
или _
. Это означает, что цифры и символы подчеркивания будут считаться символами слов, и сценарии, подобные этому, не будут выполнены:
Если вам нужно что-то более точное, вам придется начинать синтаксический синтаксис на английском языке, и это довольно большая возможность червей (и предполагает правильное использование синтаксиса, так или иначе, что не всегда является данным).
Чтобы определить, содержит ли строка другую строку, вы можете использовать функцию 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.";
}
?>
Используйте совпадение регистра с использованием stripos()
:
if (stripos($string,$stringToSearch) !== false) {
echo 'true';
}
Если вы хотите избежать «ложной» и «правдивой» проблемы, вы можете использовать substr_count:
if (substr_count($a, 'are') > 0) {
echo "at least one 'are' is present!";
}
Это немного медленнее, чем strpos, но это позволяет избежать проблем сравнения.
Отвечайте на комментарии 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
)
CASE 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
)
CASE 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. Подстановка словаря
Заменяйте слова другими, которые имеют одинаковое или сходное значение. (например: заменить случаи «голодного» и «голодного» на «голод»)
Дальнейшие алгоритмические меры (снежный ком) могут быть выполнены для дальнейшего сокращения слов до их существенного значения.
Замена названий цветов шестнадцатеричными эквивалентами
Уменьшение числовых значений за счет снижения точности - это другие способы нормализации текста.
РЕСУРСЫ
Другой вариант - использовать функцию 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_
функций.
Хорошая статья, чтобы понять, почему The Absolute Minimum Каждый разработчик программного обеспечения абсолютно уверен, должен знать о юникоде и наборах символов (никаких оправданий!) Джоэл Спольски .
Функция ниже также работает и не зависит от какой-либо другой функции; он использует только встроенные манипуляции с 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
if (preg_match('are', $a)) {
echo 'true';
}
У меня были проблемы с этим, и, наконец, я решил создать собственное решение. Без использования механизма регулярных выражений :
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
.
В 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)
Вы можете использовать функцию 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 ";
}
Чтобы найти «слово», а не появление ряда букв, которые могли бы быть частью другого слова, было бы хорошим решением.
$string = 'How are you?';
$array = explode(" ", $string);
if (in_array('are', $array) ) {
echo 'Found the word';
}
Краткосрочная версия
$result = false!==strpos($a, 'are');
Другой вариант поиска появления слова из строки с использованием strstr () и stristr () выглядит следующим образом:
<?php
$a = 'How are you?';
if (strstr($a,'are')) // Case sensitive
echo 'true';
if (stristr($a,'are')) // Case insensitive
echo 'true';
?>
Это можно сделать тремя способами:
$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
}
Вы должны использовать нечувствительный к регистру формат, поэтому, если введенное значение находится в 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";
}
?>
Здесь stripos находит иглу в heystack без рассмотрения случая (small /caps).
Много ответов, которые используют substr_count
если результат равен >0
. Но так как оператор if
считает, что ноль не совпадает с ложным , вы можете избежать этой проверки и записи напрямую:
if (substr_count($a, 'are')) {
Для того, чтобы проверить , если нет, добавить !
оператора:
if (!substr_count($a, 'are')) {
Возможно, вы могли бы использовать что-то вроде этого:
<?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';
}
Вам нужно использовать идентичные /не идентичные операторы, потому что strpos может возвращать 0 как значение индекса. Если вам нравятся тернарные операторы, подумайте о том, чтобы использовать следующее (кажется немного назад, я соглашусь):
echo FALSE === strpos($a,'are') ? 'false': 'true';
Если вы хотите проверить, содержит ли строка несколько специфических слов, вы можете:
$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, иначе оно вернет позицию слова.
Проверьте, содержит ли строка определенные слова?
Это означает, что строка должна быть разрешена в слова (см. Примечание ниже).
Один из способов сделать это и указать разделители - использовать 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 и может варьироваться, если происходит сопоставление по конкретному языку (..)
Строку можно проверить с помощью следующей функции:
function either_String_existor_not($str, $character) {
if (strpos($str, $character) !== false) {
return true;
}
return false;
}
Использование:
$text = 'This is a test';
echo substr_count($text, 'is'); // 2
// So if you want to check if is exists in the text just put
// in a condition like this:
if (substr_count($text, 'is') > 0) {
echo "is exists";
}
Более простой вариант:
return ( ! empty($a) && strpos($a, 'are'))? true : false;
Другое решение для конкретной строки:
$subject = 'How are you?';
$pattern = '/are/';
preg_match($pattern, $subject, $match);
if ($match[0] == 'are') {
echo true;
}
Вы также можете использовать strpos()
функцию.
Использование:
$a = 'How are you?';
if (mb_strpos($a, 'are')) {
echo 'true';
}
Он выполняет многобайтную безопасную операцию strpos ().
Я думаю, что хорошая идея - использовать mb_stpos
:
$haystack = 'How are you?';
$needle = 'are';
if (mb_strpos($haystack, $needle) !== false) {
echo 'true';
}
Поскольку это решение чувствительно к регистру и безопасно для всех символов Юникода .
Но вы также можете сделать это так ( ответа еще не было ):
if (count(explode($needle, $haystack)) > 1) {
echo 'true';
}
Это решение также чувствительно к регистру и безопасно для символов Юникода .
Кроме того, вы не используете отрицание в выражении , что повышает читаемость кода .
Вот другое решение, использующее функцию :
function isContainsStr($haystack, $needle) {
return count(explode($needle, $haystack)) > 1;
}
if (isContainsStr($haystack, $needle)) {
echo 'true';
}
Вы также можете использовать встроенные функции strchr()
и strrchr()
и расширения для многобайтовых строк mb_strchr()
и mb_strrchr()
. Эти функции возвращают части строк, а FALSE
если ничего не найдено.
strchr()
- Найти первое вхождение строки (это псевдоним strstr()
). strrchr()
- Найти последнее вхождение символа в строке.