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

считаем:

$a = 'How are you?';

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

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

30 ответов


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

$a = 'How are you?';

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

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


вы можете использовать регулярные выражения, это лучше для сопоставления слов по сравнению с strpos, как упоминалось другими пользователями, он также вернет true для строк, таких как тариф, уход, взгляд и т. д. Этого можно просто избежать в регулярном выражении, используя границы слов.

простое совпадение для are может выглядеть примерно так:

$a = 'How are you?';

if (preg_match('/\bare\b/',$a))
    echo 'true';

на стороне производительности strpos примерно в три раза быстрее и имейте в виду, когда я сделал миллион сравнений сразу, это заняло preg матч 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 или _. Это означает, что цифры и подчеркивания будут учитываться как символы word и сценарии, подобные этому, потерпят неудачу:

  • "в" в "Что ты думаешь?"
  • в "" в "лол у Незнайки ВТУ тех are4?"

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


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


посмотреть 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.";
    }
?>

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


использовать case-insensitve соответствия используя stripos():

if (stripos($string,$stringToSearch) !== false) {
    echo 'true';
}

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

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

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


Peer к комментариям SamGoody и Lego Stormtroopr.

если вы ищете алгоритм PHP в ранжировать результаты поиска на основе близости / релевантности из нескольких слов вот быстрый и простой способ генерации результатов поиска только с помощью PHP:

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

  1. не удается найти несколько слова!--27-->
  2. результаты unranked

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. Замена словаря

    • замените слова другими, которые имеют одинаковое или подобное значение. (пример:замените примеры "голодный" и "голодный" на "голодный")

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

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

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

    ресурсы


    другой вариант-использовать 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 и наборах символов (без оправданий!) by Джоэл Спольски.


    функция ниже также работает и не зависит от какой-либо другой функции; она использует только собственные строки 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;
      }
    }
    

    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.


    можно использовать 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 ";
    }
    

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

    короткая версия

    $result = false!==strpos($a, 'are');
    

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

    $string = 'How are you?';
    $array = explode(" ", $string);
    
    if (in_array('are', $array) ) {
        echo 'Found the word';
    }
    

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

    <?php
        $a = 'How are you?';
        if (strstr($a,'are'))  // Case sensitive
            echo 'true';
        if (stristr($a,'are'))  // Case insensitive
            echo 'true';
    ?>
    

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

    образец PHPCode с выходом


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

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

    много ответов, которые используют substr_count проверяет, является ли результат >0. Но с тех пор if заявление считает нулю то же, что и false, вы можете избежать этой проверки и написать напрямую:

    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() или как они будут быстрее. (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;
    }