Как проверить, содержит ли строка определенное слово?

Рассмотрим:

$a = 'How are you?';

if ($a contains 'are')
    echo 'true';

Предположим, что у меня есть код выше, каков правильный способ написать оператор if ($a contains 'are')?

2422
задан Charles Yeung 06 дек. '10 в 16:14
источник поделиться
39 ответов
  • 1
  • 2

Вы можете использовать функцию strpos(), которая используется для поиска вхождения одной строки внутри другой:

$a = 'How are you?';

if (strpos($a, 'are') !== false) {
    echo 'true';
}

Обратите внимание, что использование !== false является преднамеренным; strpos() возвращает либо смещение, при котором начинается строка иглы в строке стога сена, или логическое false, если игла не найдена. Поскольку 0 является допустимым смещением и 0 является "ложным", мы не можем использовать более простые конструкции, такие как !strpos($a, 'are').

4749
ответ дан codaddict 06 дек. '10 в 16:15
источник поделиться

Вы можете использовать регулярные выражения. Он будет выглядеть примерно так:

$a = 'How are you?';

if (preg_match('/are/',$a))
    echo 'true';

Не говори мне, что это плохо, потому что ты слышал это плохо. Вы можете, если у вас есть какие-либо факты, чтобы поддержать его, хотя;)

С точки зрения производительности, strpos примерно в три раза быстрее и имеет в виду, когда я сделал один миллион сравнений сразу, потребовалось догонять матч за 1,5 секунды, а для strpos - 0,5 секунды. Я пытаюсь сказать, что он работает очень быстро в любом случае. Если у вас нет 100 000 посетителей каждую секунду, вы не должны беспокоиться о таких вещах и брать то, что наиболее удобно, ИМО.

375
ответ дан Breezer 06 дек. '10 в 16:15
источник поделиться

Используйте strpos:

if (strpos($a, 'are') !== false)
    echo 'true';
245
ответ дан Milan Babuškov 06 дек. '10 в 16:15
источник поделиться

Вот небольшая полезная функция, которая полезна в таких ситуациях

// returns true if $needle is a substring of $haystack
function contains($needle, $haystack)
{
    return strpos($haystack, $needle) !== false;
}
171
ответ дан ejunker 18 авг. '11 в 21:54
источник поделиться

В то время как большинство этих ответов скажут вам, будет ли подстрока отображаться в вашей строке, что обычно не то, что вы хотите, если вы ищете конкретное слово, а не подстроку.

Какая разница? Подстроки могут отображаться иными словами:

  • "находятся" в начале "area"
  • "находятся" в конце "заяц"
  • "находятся" в середине "тарифов"

Одним из способов смягчения этого является использование регулярного выражения в сочетании с границами слов (\b):

function containsWord($str, $word)
{
    return !!preg_match('#\\b' . preg_quote($word, '#') . '\\b#i', $str);
}

Этот метод не имеет таких же ложных срабатываний, как указано выше, но у него есть некоторые краевые случаи. Границы слов совпадают с символами без слов (\W), которые будут не такими, как a-z, a-z, 0-9 или _. Это означает, что цифры и символы подчеркивания будут считаться символами слов, и сценарии, подобные этому, не будут выполняться:

  • "Есть" в "Что вы думаете?"
  • "есть" в "lol u dunno wut that are4?"

Если вам нужно что-то более точное, вам нужно будет начать синтаксический анализ синтаксиса на английском языке, и это довольно большая червь червей (и предполагает правильное использование синтаксиса, во всяком случае, которое не всегда является данным).

95
ответ дан FtDRbwLXw6 03 сент. '14 в 2:23
источник поделиться

Чтобы определить, содержит ли строка другую строку, вы можете использовать функцию 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, если вы выполните сравнение ==, которое не будет работать, вам нужно будет сделать ===

Знак A == - это сравнение и проверяет, имеет ли переменная/выражение/константа влево то же значение, что и переменная/выражение/константа справа.

Знак A === - это сравнение, чтобы увидеть, равны ли две переменные/выражения/константы AND того же типа, т.е. оба являются строками, или оба являются целыми числами.

82
ответ дан Jose Vega 06 дек. '10 в 17:06
источник поделиться

Используя strstr() или stristr(), если ваш поиск должен быть нечувствительным к регистру, будет другим вариантом.

51
ответ дан glutorange 06 дек. '10 в 17:16
источник поделиться

Посмотрите strpos():

<?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.";
    }
?>
50
ответ дан Haim Evgi 06 дек. '10 в 16:16
источник поделиться

Если вы хотите избежать "ложной" и "правдивой" проблемы, вы можете использовать substr_count:

if (substr_count($a, 'are') > 0) {
    echo "at least one 'are' is present!";
}

Это немного медленнее, чем strpos, но это позволяет избежать проблем с сопоставлением.

35
ответ дан Alan Piralla 09 июля '13 в 11:38
источник поделиться

Используйте аргумент без учета регистра, используя stripos():

if (stripos($string,$stringToSearch) !== false) {
    echo 'true';
}
34
ответ дан Shankar Damodaran 24 окт. '13 в 10:30
источник поделиться

Другой вариант - использовать функцию strstr(). Что-то вроде:

if (strlen(strstr($haystack,$needle))>0) {
// Needle Found
}

Указание на заметку: функция strstr() чувствительна к регистру. Для поиска без учета регистра используйте функцию stristr().

28
ответ дан YashG99 20 авг. '12 в 19:20
источник поделиться

Отклики на комментарии SamGoody и Lego Stormtroopr.

Если вы ищете php-алгоритм для ранговых результатов поиска на основе близости/релевантности нескольких слов здесь идет быстрый и простой способ генерации результатов поиска только с PHP:

Проблемы с другими методами булевого поиска sush как strpos(), preg_match(), strstr() или stristr()

  • не может найти несколько слов
  • результаты не выполняются

PHP-метод, основанный на Vector Space Model и 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 fro  high to low

        arsort($similar_documents);

    }   

    return $similar_documents;
}

CASE 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
)

Существует множество улучшений но модель обеспечивает способ получения хороших результатов от естественных запросов, которые не имеют логических операторов sush как strpos(), preg_match(), strstr() или stristr().

NOTA BENE

Опционально исключая избыточность до поиска слов

  • что уменьшает размер индекса и приводит к меньшему требованию к хранению

  • меньше дискового ввода-вывода

  • более быстрая индексация и, следовательно, быстрый поиск.

1. Нормализация

  • Преобразование всего текста в нижний регистр

2. Прекратить удаление слов

  • Исключить слова из текста, которые не имеют реального значения (например, "и", "или", "the", "for" и т.д.).

3. Подстановка словаря

  • Заменить слова другими, имеющими идентичный или похожий смысл. (например: заменить случаи "голодного" и "голодного" на "голод" )

  • Дополнительные алгоритмические меры (снежный ком) могут быть выполнены для дальнейшего сокращения слов до их существенного значения.

  • Замена имен цветов шестнадцатеричными эквивалентами

  • Уменьшение числовых значений за счет уменьшения точности - это другие способы нормализации текста.

РЕСУРСЫ

25
ответ дан RafaSashi 15 окт. '14 в 22:21
источник поделиться

Я немного впечатлен тем, что ни один из ответов здесь, в которых использовались strpos, strstr и подобные функции, упоминалось Многобайтовые строковые функции пока (2015-05-08).

В принципе, если вы не можете найти слова с символами, характерными для некоторых языков, такими как немецкий, французский, португальский, испанский и т.д. (например: ä, é, ô, ç, º, ñ), вы можете захотеть предшествовать функциям с помощью mb_. Поэтому принятый ответ будет использовать mb_strpos или mb_stripos (для нечувствительности к регистру):

if (mb_strpos($a,'are') !== false) {
    echo 'true';
}

Если вы не можете гарантировать, что все ваши данные на 100% в UTF-8, вы можете использовать функции mb_.

Хорошая статья, чтобы понять, почему Абсолютный минимум Каждый разработчик программного обеспечения Абсолютно, положительно должен знать о Unicode и наборах символов (без отговорок!) Джоэл Спольский.

24
ответ дан Armfoot 08 мая '15 в 19:18
источник поделиться

Функция ниже также работает и не зависит от какой-либо другой функции; он использует только встроенные манипуляции с 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 first char == string 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 first char == string 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 
21
ответ дан Jason OOO 19 сент. '13 в 17:00
источник поделиться
if (preg_match('are', $a)) {
   echo 'true';
}
20
ответ дан joan16v 10 окт. '13 в 14:22
источник поделиться

У меня были проблемы с этим, и, наконец, я решил создать собственное решение. Без использования регулярное выражение engine:

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.

18
ответ дан decebal 18 марта '14 в 18:49
источник поделиться

Вы можете использовать функцию 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 ";
}
15
ответ дан Arshid KV 27 авг. '15 в 19:59
источник поделиться

Чтобы найти слово, а не появление ряда букв, которые могли бы быть частью другого слова, было бы хорошим решением.

$string = 'How are you?';
$array = explode(" ", $string);

if (in_array('are', $array) ) {
    echo 'Found the word';
}
12
ответ дан C Ivemy 17 апр. '15 в 9:31
источник поделиться

Еще одна возможность найти появление слова из строки с помощью strstr() и stristr() выглядит следующим образом:

<?php
    $a = 'How are you?';
    if (strstr($a,'are'))  // Case sensitive
        echo 'true';
    if (stristr($a,'are'))  // Case insensitive
        echo 'true';
?>
12
ответ дан Sadikhasan 13 марта '14 в 8:48
источник поделиться

Вы должны использовать регистр, нечувствительный, поэтому, если введенное значение находится в 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).

Пример PHPCode с выходом

12
ответ дан Pratik C Joshi 03 марта '15 в 22:02
источник поделиться

Краткосрочная версия

$result = false!==strpos($a, 'are');
12
ответ дан Somwang Souksavatd 13 марта '15 в 11:29
источник поделиться
$a = 'how are you';
if (strpos($a,'are')) {
    echo 'true';
}
11
ответ дан Dávid 09 окт. '12 в 19:17
источник поделиться

Это можно сделать тремя способами:

 $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
 }
11
ответ дан Shashank Singh 19 дек. '15 в 13:57
источник поделиться

Возможно, вы могли бы использовать что-то вроде этого:

<?php
    findWord('Test all OK');

    function findWord($text) {
        if (strstr($text, 'ok')) {
            echo 'Found a word';
        }
        else
        {
            echo 'Did not find a word';
        }
    }
?>
11
ответ дан Mathias Stavrou 07 апр. '15 в 15:51
источник поделиться

В 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)
10
ответ дан John Slegers 21 февр. '16 в 21:39
источник поделиться

Не используйте preg_match(), если вы хотите только проверить, содержится ли одна строка в другой строке. Вместо этого используйте strpos() или strstr(), поскольку они будут быстрее. (http://in2.php.net/preg_match)

if (strpos($text, 'string_name') !== false){
   echo 'get the string';
}
10
ответ дан Vinod Joshi 05 апр. '14 в 14:17
источник поделиться

Если вы хотите проверить, содержит ли строка несколько специальных слов, вы можете сделать:

$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";
}

Это полезно, чтобы избежать спама при отправке писем, например.

8
ответ дан Julien 14 окт. '15 в 17:40
источник поделиться

Вам нужно использовать идентичные/не идентичные операторы, потому что strpos может возвращать 0 в качестве значения индекса. Если вам нравятся тернарные операторы, подумайте о том, чтобы использовать следующее (кажется немного назад, я соглашусь):

echo FALSE === strpos($a,'are') ? 'false': 'true';
8
ответ дан Shapeshifter 15 окт. '14 в 22:47
источник поделиться

Функция 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, иначе оно вернет позицию слова.

7
ответ дан Akshay Khale 31 мая '15 в 8:52
источник поделиться

Проверьте, содержит ли строка определенные слова?

Это означает, что строка должна быть разрешена в слова (см. примечание ниже).

Один из способов сделать это и указать разделители: 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 таблиц и может варьироваться, если выполняется соответствие по языку (..)

6
ответ дан mvw 24 сент. '15 в 1:16
источник поделиться
  • 1
  • 2

Другие вопросы по меткам