Como posso verificar se um texto contém uma palavra específica?

considere:

$a = 'How are you?';

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

suponha que eu tenho o código acima, qual é a maneira correta de escrever a declaração if ($a contains 'are')?

Author: Charles Yeung , 2010-12-06

30 answers

Podes usar o strpos() função que é usada para encontrar a ocorrência de uma cadeia dentro de outra:

$a = 'How are you?';

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

Lembre-se que a utilização de !== false é deliberada; strpos() devolve a posição em que a corda da agulha começa na corda do Palheiro, ou o booleano false se a agulha não for encontrada. Uma vez que 0 é um offset válido e 0 é "falsey", não podemos usar construções mais simples como !strpos($a, 'are').

 5583
Author: codaddict, 2017-08-07 13:49:38

Você poderia usar expressões regulares, é melhor para correspondência de Palavras em comparação com strpos como mencionado por outros usuários que também retornará verdadeiro para strings, tais como tarifa, cuidado, olhar, etc. Isto pode simplesmente ser evitado na expressão regular usando limites de palavras.

Um jogo simples para are pode ser parecido com isto:

$a = 'How are you?';

if (preg_match('/\bare\b/',$a))
    echo 'true';
Do lado da performance, o strpos é três vezes mais rápido e tem em mente que, quando fiz um milhão de comparações ao mesmo tempo, foi preciso um jogo de prég de 1,5. segundos para terminar e para strpos levou 0,5 segundos.
 464
Author: Breezer, 2018-01-20 09:52:28

Aqui está uma pequena função útil que é útil em situações como esta

// returns true if $needle is a substring of $haystack
function contains($needle, $haystack)
{
    return strpos($haystack, $needle) !== false;
}
 203
Author: ejunker, 2011-08-18 18:54:47

Embora a maioria destas respostas lhe digam se uma substring aparece na sua string, normalmente não é o que quer se está à procura de uma palavra em particular , e não de uma substring .

Qual é a diferença? Substratos podem aparecer em outras palavras:
  • O " são "no início da"área"
  • O " são "no fim da"lebre"
  • Os "estão" no meio das "tarifas"
Uma maneira de mitigar isto seria usar um expressão regular associada aos limites das palavras (\b):
function containsWord($str, $word)
{
    return !!preg_match('#\\b' . preg_quote($word, '#') . '\\b#i', $str);
}

Este método não tem os mesmos falsos positivos assinalados acima, mas tem alguns casos extremos próprios. Os limites das palavras coincidem com os caracteres não-Palavra (\W), que vão ser qualquer coisa que não sejaa-z, A-Z, 0-9, ou _. Isso significa que os dígitos e os sublinhados serão contados como caracteres de palavra e cenários como este falharão:

  • O " são " em " O que _ are_ você a pensar?"
  • O "são" em "lol u don't wut those are4?"

Se você quiser algo mais preciso do que isso, você terá que começar a fazer o processamento de sintaxe em língua inglesa, e isso é uma grande lata de worms (e assume o uso adequado da sintaxe, de qualquer maneira, o que nem sempre é um dado).

 117
Author: FtDRbwLXw6, 2017-01-22 14:39:58

Para determinar se uma cadeia contém outra cadeia de caracteres, poderá usar a função 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";
}

?>

Atenção:

Se a agulha que procura estiver no início do Palheiro, irá devolver a posição 0, Se fizer uma comparação == que não irá funcionar, terá de fazer uma ===

Um sinal == é uma comparação e testes se a variável / expressão / constante à esquerda tem o mesmo valor que o valor variável / expressão / constante à direita.

A === sign é uma comparação para ver se duas variáveis / expresões / constantes são iguais AND têm o mesmo tipo - ou seja, ambos são cadeias ou ambos são inteiros.

 96
Author: Jose Vega, 2018-07-30 10:03:48

Olha para 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.";
    }
?>
 57
Author: Haim Evgi, 2013-09-24 18:28:24

Utilizar strstr() ou stristr() se a sua pesquisa não for sensível a maiúsculas, será outra opção.

 57
Author: glutorange, 2013-09-24 18:31:57

Faça uso de case-insensitve matching Usando stripos():

if (stripos($string,$stringToSearch) !== false) {
    echo 'true';
}
 39
Author: Shankar Damodaran, 2014-05-25 03:49:35

Se quiser evitar o problema" falsey "e" truthy", pode usar o subconjunto:

if (substr_count($a, 'are') > 0) {
    echo "at least one 'are' is present!";
}
É um pouco mais lento que o strpos, mas evita os problemas de comparação.
 37
Author: Alan Piralla, 2013-07-09 08:38:53
Peer to SamGoody and Lego Stormtroopr comments.

Se está à procura de um algoritmo de PHP para os resultados de pesquisa de classificação com base na proximidade / relevância de várias palavras aqui vem uma maneira rápida e fácil de gerar resultados de pesquisa apenas com PHP:

Problemas com os outros métodos de busca booleanos, como strpos(), preg_match(), strstr() ou stristr()

  1. não se pode procurar por várias palavras
  2. os resultados não têm fundamento

PHP método baseado em Vector Space Model e tf-idf (term frequency-inverse document frequency):

Parece difícil, mas é surpreendentemente fácil. Se queremos procurar por várias palavras numa cadeia, o problema principal é como atribuímos um peso a cada uma delas?

Se pudéssemos pesar os Termos numa string baseada no quão representativos eles são da string como um todo, podemos encomendar os nossos resultados por aqueles que melhor correspondem à consulta.

Esta é a ideia do modelo de espaço vetorial, não muito longe de como a pesquisa de texto completo SQL funciona:

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

Processo 1

$query = 'are';

$corpus = array(
    1 => 'How are you?',
);

$match_results=get_similar_documents($query,$corpus);
echo '<pre>';
    print_r($match_results);
echo '</pre>';

RESULTADO

Array
(
    [1] => 0.52832083357372
)

Processo 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>';

Resultados

Array
(
    [1] => 0.54248125036058
    [3] => 0.21699250014423
)

Processo 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>';

Resultados

Array
(
    [3] => 0.6813781191217
    [1] => 0.54248125036058
)
Há muitas melhorias a fazer. mas o modelo oferece uma maneira de obter bons resultados de consultas naturais, que não existem operadores booleanos como strpos(), preg_match(), strstr() ou stristr().

NOTA BENE

opcionalmente eliminar a redundância antes de procurar as palavras

  • Reduzindo assim a dimensão do índice e reduzindo as necessidades de armazenamento

  • Menos disco I / O

  • Indexação mais rápida e, consequentemente, uma busca mais rápida.

1. Normalização

  • converter todo o texto para baixo processo

2. Eliminação da palavra-chave

  • eliminar palavras do texto que não têm significado real (como 'e',' ou',' o',' para', etc.)

3. Substituição do dicionário

  • Substituir palavras por outras que tenham um significado idêntico ou semelhante. (ex:substituir os casos de "fome" e "fome" por "fome"')

  • Outras medidas algorítmicas (bola de neve) podem ser realizadas para reduzir ainda mais palavras para o seu significado essencial.

  • Substituição dos nomes de cores pelos seus equivalentes hexadecimais

  • A redução dos valores numéricos pela redução da precisão são outras formas de normalizar o texto.

Recursos

 36
Author: RafaSashi, 2017-12-24 11:14:57

Outra opção é usar a função strstr(). Algo do género:

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

Ponto a ter em conta: a função strstr () é sensível à capitalização. Para uma pesquisa sem distinção de maiúsculas, use a função stristr().

 31
Author: YashG99, 2012-08-20 16:20:31
Estou um pouco impressionado que nenhuma das respostas aqui que usaram strpos, strstr e funções similares mencionadas funções de cadeia de múltiplos ainda (2015-05-08).

Basicamente, se você está tendo dificuldade em encontrar palavras com caracteres específicos para algumas línguas , Como Alemão, Francês, Português, Espanhol, etc. (exemplo: ä, é, ô, ç, º, ñ), poderá preceder as funções com mb_. Por conseguinte, a resposta aceite utilizaria mb_strpos ou mb_stripos (para a correspondência sem distinção de maiúsculas) em vez disso:

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

Se não puder garantir isso todos os seus dados são 100% em UTF-8, pode querer usar as funções mb_.

Um bom artigo para entender porque O mínimo absoluto de cada desenvolvedor de Software absolutamente, positivamente deve saber sobre Unicode e conjuntos de caracteres (sem desculpas!) por Joel Spolsky.
 29
Author: Armfoot, 2017-05-23 12:34:57

A função abaixo também funciona e não depende de nenhuma outra função; ela usa apenas manipulação de cadeia de Php nativa. Pessoalmente, eu não recomendo isso, mas você pode ver como funciona:

<?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;
  }
}

Teste:

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 
 24
Author: Jason OOO, 2015-05-18 10:45:06
if (preg_match('are', $a)) {
   echo 'true';
}
 23
Author: joan16v, 2015-12-23 14:00:42
Tive alguns problemas com isto, e finalmente escolhi criar a minha própria solução. Sem utilizar a expressão regular Motor:
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;
 }

Você pode notar que as soluções anteriores não são uma resposta para a palavra sendo usada como um prefixo para outra. Para usar o seu exemplo:

$a = 'How are you?';
$b = "a skirt that flares from the waist";
$c = "are";

Com as amostras acima, $a e $b contêm $c, mas pode querer que a sua função lhe diga que apenas $a contém $c.

 21
Author: Decebal, 2016-06-25 19:30:08

Pode usar a função strstr:

$haystack = "I know programming";
$needle   = "know";
$flag = strstr($haystack, $needle);

if ($flag){

    echo "true";
}

Sem usar uma função incorporada:

$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 ";
}
 20
Author: Arshid KV, 2017-05-21 11:26:37

Em PHP, a melhor maneira de verificar se uma cadeia contém uma determinada substring, é usar uma função auxiliar simples como esta:

function contains($haystack, $needle, $caseSensitive = false) {
    return $caseSensitive ?
            (strpos($haystack, $needle) === FALSE ? FALSE : TRUE):
            (stripos($haystack, $needle) === FALSE ? FALSE : TRUE);
}

Explicação:

  • strpos Encontra a posição da primeira ocorrência de uma sub-sequência sensível a maiúsculas numa cadeia de caracteres.
  • stripos Encontra a posição da primeira ocorrência de um sub-texto sem distinção de maiúsculas numa cadeia de caracteres.
  • myFunction($haystack, $needle) === FALSE ? FALSE : TRUE assegura que myFunction devolve sempre um booleano e corrige o inesperado comportamento quando o índice da sub-estrutura é 0.
  • $caseSensitive ? A : B seleciona strpos ou stripos para fazer o trabalho, dependendo do valor de $caseSensitive.

Resultado:

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)
 20
Author: John Slegers, 2017-12-12 16:48:01

A versão em mão curta

$result = false!==strpos($a, 'are');
 16
Author: Somwang Souksavatd, 2016-03-20 17:38:15

A fim de encontrar uma 'palavra', ao invés da ocorrência de uma série de letras que poderiam de fato ser uma parte de outra palavra, o seguinte seria uma boa solução.

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

if (in_array('are', $array) ) {
    echo 'Found the word';
}
 16
Author: DJC, 2016-06-25 19:25:09

Outra opção para encontrar a ocorrência de uma palavra a partir de uma seqüência de caracteres usando strstr() e stristr() é como a seguinte:

<?php
    $a = 'How are you?';
    if (strstr($a,'are'))  // Case sensitive
        echo 'true';
    if (stristr($a,'are'))  // Case insensitive
        echo 'true';
?>
 15
Author: Sadikhasan, 2016-06-25 19:30:52

Deverá usar um formato insensível à capitalização, por isso, se o valor indicado estiver em small ou caps, não importa.

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

Aqui as listras encontram a agulha na seringa Sem considerando o caso (pequenas/tampas).

Amostra de código PHP com saída

 14
Author: Pratik C Joshi, 2015-09-08 11:00:06

Pode ser feito de três maneiras diferentes:

 $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
 }
 14
Author: Shashank Singh, 2015-12-28 04:28:02

Muitas respostas que usam substr_count verifica se o resultado é >0. Mas uma vez que a declaração if considera zero o igual a falso , Você pode evitar essa verificação e escrever diretamente:

if (substr_count($a, 'are')) {

Para verificar se não está presente, adicione o ! operador:

if (!substr_count($a, 'are')) {
 14
Author: T30, 2017-12-21 11:21:22
Talvez precises de algo assim.
<?php
    findWord('Test all OK');

    function findWord($text) {
        if (strstr($text, 'ok')) {
            echo 'Found a word';
        }
        else
        {
            echo 'Did not find a word';
        }
    }
?>
 13
Author: Mathias Stavrou, 2016-06-25 19:26:54

Não utilize preg_match() se só quiser verificar se um texto está contido noutro texto. Utilize strpos() ou strstr() em vez disso, pois serão mais rápidos. ([6]} http://in2.php.net/preg_match)

if (strpos($text, 'string_name') !== false){
   echo 'get the string';
}
 11
Author: Vinod Joshi, 2014-04-05 11:49:13

Você precisa usar operadores idênticos / não idênticos porque strpos pode retornar 0 como o seu valor de índice. Se você gosta de operadores ternários, considere usar o seguinte (parece um pouco para trás eu admito):

echo FALSE === strpos($a,'are') ? 'false': 'true';
 10
Author: Shapeshifter, 2016-02-21 18:25:42

Se quiser verificar se o texto contém várias palavras específicas, pode fazer:

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

Isto é útil para evitar spam ao enviar e-mails, por exemplo.

 10
Author: Julien, 2016-06-25 19:17:33

A função strpos funciona bem, mas se você quiser fazer case-insensitive a verificação de uma palavra num parágrafo então você pode fazer uso da função stripos de PHP.

Por exemplo,

$result = stripos("I love PHP, I love PHP too!", "php");
if ($result === false) {
    // Word does not exist
}
else {
    // Word exists
}

Encontre a posição da primeira ocorrência de um sub-texto insensível a maiúsculas numa cadeia de caracteres.

Se a palavra não existe na cadeia então ela retornará falsa caso contrário retornará a posição da palavra.

 9
Author: Akshay Khale, 2017-01-05 14:16:57

Verificar se o texto contém palavras específicas?

Isto significa que o texto tem de ser resolvido em palavras (Ver nota abaixo).

Uma maneira de fazer isto e especificar os separadores está a usar 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');

?>

Uma corrida dá

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

Nota: aqui não queremos dizer palavra para cada sequência de símbolos.

Uma definição prática de palavra é no sentido do motor de expressão regular PCRE, onde as palavras são substratos que consistem em apenas caracteres de palavra, sendo separados por caracteres não-Palavra.

Um carácter de "palavra" é qualquer letra ou dígito ou o carácter sublinhado, ou seja, qualquer personagem que possa ser parte de uma "palavra" Perl. O a definição de letras e dígitos é controlada pelo carácter do PCRE tables, and may vary if locale-specific matching is taking place (..)

 8
Author: mvw, 2015-09-23 23:37:08

Um texto pode ser verificado com a função abaixo:

function either_String_existor_not($str, $character) {
    if (strpos($str, $character) !== false) {
        return true;
    }
    return false;
}
 7
Author: M Razwan, 2016-07-13 03:41:47