Comment puis-je vérifier si une chaîne contient un mot en particulier?

prendre en considération:

$a = 'How are you?';

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

supposons que j'ai le code ci-dessus, Quelle est la bonne façon d'écrire l'énoncé if ($a contains 'are') ?

2667
demandé sur Charles Yeung 2010-12-06 16:14:05

30 réponses

vous pouvez utiliser la fonction strpos() qui est utilisée pour trouver l'occurrence d'une chaîne à l'intérieur d'une autre:

$a = 'How are you?';

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

notez que l'utilisation de !== false est délibérée; strpos() renvoie soit l'offset auquel la corde de l'aiguille commence dans la chaîne de la botte de foin, soit le booléen false si l'aiguille n'est pas trouvée. Puisque 0 est un offset valide et 0 est "falsey", nous ne pouvons pas utiliser des constructions plus simples comme !strpos($a, 'are') .

5583
répondu codaddict 2017-08-07 13:49:38

vous pouvez utiliser des expressions régulières, il est préférable de faire correspondre les mots par rapport à strpos comme mentionné par d'autres utilisateurs, il retournera également vrai pour les chaînes telles que fare, care, stare etc. Cela peut simplement être évité dans l'expression régulière en utilisant des limites de mots.

un simple match pour are pourrait ressembler à quelque chose comme ceci:

$a = 'How are you?';

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

côté performance, strpos est environ trois fois plus rapide et ont à l'esprit, quand j'ai fait un million compare à la fois, il a fallu preg match de 1,5 secondes pour terminer et pour strpos il a pris de 0,5 secondes.

464
répondu Breezer 2018-01-20 09:52:28

Voici une petite fonction d'utilité qui est utile dans des situations comme celle-ci""

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

alors que la plupart de ces réponses vous diront si un substrat apparaît dans votre chaîne, ce n'est généralement pas ce que vous voulez si vous cherchez un mot , et non un substrat .

quelle différence? Les substrats peuvent apparaître en d'autres mots:

  • Le "sont" au début de la "zone",
  • Le "sont" à la fin de "lièvre"
  • Le "sont" au milieu de "tarifs"

une façon d'atténuer cette situation serait d'utiliser une expression régulière couplée avec les limites de mots ( \b ):

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

cette méthode n'a pas les mêmes faux positifs mentionnés ci-dessus, mais elle a quelques cas de bord de ses propres. Les limites des mots correspondent à des caractères autres que les mots ( \W ), qui vont être tout ce qui n'est pas a-z , A-Z , 0-9 , ou _ . Cela signifie que les chiffres et les soulignements vont être comptés comme des caractères de mots et des scénarios comme celui-ci échouera:

  • le "sont" dans " Que pensez-vous?"
  • Le "sont" dans "lol u ne sais pas wut ceux are4?"

si vous voulez quelque chose de plus précis que ceci, vous devrez commencer à faire l'analyse syntaxique de langue anglaise, et c'est une assez grande boîte de vers (et suppose une utilisation correcte de la syntaxe, de toute façon, qui n'est pas toujours donnée).

117
répondu FtDRbwLXw6 2017-01-22 14:39:58

pour déterminer si une chaîne contient une autre chaîne, vous pouvez utiliser la fonction 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";
}

?>

attention:

si l'aiguille que vous recherchez est au début de la botte de foin, il retournera la position 0, si vous faites un == comparer qui ne fonctionnera pas, vous aurez besoin de faire un ===

Un == est une comparaison et teste si la variable / expression / constante de la gauche a la même valeur que la variable / expression / constante pour la droite.

a === signe est une comparaison pour voir si deux variables / expressions / constantes sont égales AND ont le même type - c.-à-d. les deux sont des chaînes ou les deux sont des entiers.

96
répondu Jose Vega 2018-07-30 10:03:48

regardez 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
répondu Haim Evgi 2013-09-24 18:28:24

utilisant strstr() ou stristr() si votre recherche devrait être insensible à la casse serait une autre option.

57
répondu glutorange 2013-09-24 18:31:57

utiliser case-insensitve matching utiliser stripos() :

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

si vous voulez éviter les problèmes "falsey" et "truthy", vous pouvez utiliser substr_count:

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

c'est un peu plus lent que strpos mais ça évite les problèmes de comparaison.

37
répondu Alan Piralla 2013-07-09 08:38:53

Peer to SamGoody and Lego Stormtroopr comments.

si vous recherchez un algorithme PHP pour classez les résultats de recherche basés sur la proximité /pertinence de mots multiples voici une façon rapide et facile de générer des résultats de recherche avec PHP seulement:

problèmes avec les autres méthodes de recherche booléennes telles que strpos() , preg_match() , strstr() ou stristr()

  1. impossible de rechercher plusieurs mots
  2. les résultats ne sont pas classés

PHP méthode fondée sur la Modèle Vectoriel et tf-idf (term frequency–inverse document de fréquence):

cela semble difficile mais est étonnamment facile.

si nous voulons rechercher plusieurs mots dans une chaîne le noyau le problème, c'est comment attribuer un poids à chacun d'eux?

si nous pouvions pondérer les Termes dans une chaîne en fonction de leur représentativité de la chaîne dans son ensemble, nous pourrions commander nos résultats par ceux qui correspondent le mieux à la requête.

C'est l'idée du modèle d'espace vectoriel, pas loin de la façon dont la recherche en texte intégral SQL fonctionne:

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

CAS 1

$query = 'are';

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

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

résultat

Array
(
    [1] => 0.52832083357372
)

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

résultats

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

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

résultats

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

Il ya beaucoup d'améliorations à faire mais le modèle fournit un moyen d'obtenir de bons résultats naturels des requêtes, qui n'ont pas d'opérateurs booléens tels que strpos() , preg_match() , strstr() ou stristr() .

NOTA BENE

suppression facultative de la redondance avant de rechercher les mots

  • ce qui réduit la taille de l'indice et réduit les besoins de stockage

  • moins disque I / O

  • indexation plus rapide et, par conséquent, recherche plus rapide.

1. Normalisation "de la 1519190920"

  • convertir tout le texte en minuscules

2. Suppression du mot-clé

"
  • supprimer les mots du texte qui effectuer aucune signification réelle (comme 'et', 'ou', 'la', 'pour', etc.)

3. Substitution du dictionnaire

  • remplacer les mots avec d'autres qui ont un sens identique ou similaire. (ex:remplacer "hungrily" et "hungrily" par "hunger")

  • D'autres mesures algorithmiques (boule de neige) peuvent être effectuées pour réduire davantage les mots à leur signification essentielle.

  • le remplacement des noms de couleur par leurs équivalents hexadécimaux

  • la réduction des valeurs numériques par la réduction de la précision sont d'autres moyens de normaliser le texte.

ressources

36
répondu RafaSashi 2017-12-24 11:14:57

une autre option est d'utiliser la fonction strstr () . Quelque chose comme:

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

point à noter: la fonction strstr() est sensible à la casse. Pour une recherche non sensible à la casse, utilisez la fonction stristr() .

31
répondu YashG99 2012-08-20 16:20:31

je suis un peu impressionné qu'aucune des réponses ici qui a utilisé strpos , strstr et des fonctions similaires mentionnées Multibyte String Functions encore (2015-05-08).

en gros, si vous êtes ayant de la difficulté à trouver des mots avec des caractères spécifiques à certaines langues , tels que l'allemand, le français, le portugais, l'espagnol, etc. (par exemple: ä , é , ô , ç , º , - ), vous pouvez faire précéder les fonctions mb_ . Par conséquent, la réponse acceptée serait mb_strpos ou mb_stripos (for case-insensitive matching) instead:

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

si vous ne pouvez pas garantir que toutes vos données sont 100% en UTF-8 , vous peut vouloir utiliser les fonctions mb_ .

un bon article pour comprendre pourquoi est le Minimum absolu chaque développeur de logiciel absolument, positivement doit savoir sur Unicode et jeux de caractères (pas D'Excuses!) par Joel Spolsky .

29
répondu Armfoot 2017-05-23 12:34:57

la fonction ci-dessous fonctionne également et ne dépend d'aucune autre fonction; elle utilise uniquement la manipulation de chaîne de caractères PHP native. Personnellement, je ne le recommande pas, mais vous pouvez voir comment cela fonctionne:

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

essai:

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
répondu Jason OOO 2015-05-18 10:45:06
if (preg_match('are', $a)) {
   echo 'true';
}
23
répondu joan16v 2015-12-23 14:00:42

j'ai eu quelques difficultés avec cela, et finalement j'ai choisi de créer ma propre solution. Sans utiliser expression régulière moteur:

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

vous remarquerez que les solutions précédentes ne sont pas une réponse pour le mot utilisé comme préfixe pour un autre. Afin d'utiliser votre exemple:

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

avec les échantillons ci-dessus, les deux $a et $b contient $c , mais vous pouvez vouloir votre fonction pour vous dire que seul $a contient $c .

21
répondu Decebal 2016-06-25 19:30:08

vous pouvez utiliser la fonction strstr :

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

if ($flag){

    echo "true";
}

sans utiliser une fonction intégrée:

$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
répondu Arshid KV 2017-05-21 11:26:37

en PHP, la meilleure façon de vérifier si une chaîne contient un certain substrat, est d'utiliser une fonction d'aide simple comme celle-ci:

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

explication:

  • strpos trouve la position de la première occurrence d'un substrat sensible à la casse dans une chaîne.
  • stripos trouve la position de la première occurrence d'un insensible à la casse sous-chaîne dans une chaîne.
  • myFunction($haystack, $needle) === FALSE ? FALSE : TRUE assure que myFunction renvoie toujours un booléen et fixe un comportement inattendu lorsque l'indice de la chaîne est 0.
  • $caseSensitive ? A : B sélectionne strpos ou stripos pour effectuer le travail, selon la valeur de $caseSensitive .

sortie:

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
répondu John Slegers 2017-12-12 16:48:01

la version courte

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

afin de trouver un "mot", plutôt que de la survenance d'une série de lettres qui pourraient en fait être une partie d'un autre mot, le suivant serait une bonne solution.

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

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

une autre option pour trouver l'occurrence d'un mot d'une chaîne utilisant strstr() et stristr() est comme suit:

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

vous devez utiliser le format insensible à la casse,donc si la valeur entrée est dans small ou caps il n'aura pas d'importance.

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

ici stripos trouve l'aiguille dans la meule de foin sans compte tenu du cas (petits/capuchons).

échantillon de PHPCode avec sortie

14
répondu Pratik C Joshi 2015-09-08 11:00:06

cela peut être fait de trois façons différentes:

 $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
répondu Shashank Singh 2015-12-28 04:28:02

Lot de réponses qui utilisent substr_count vérifie si le résultat est >0 . Mais puisque le if considère zéro le même que faux , vous pouvez éviter ce contrôle et écrire directement:

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

pour vérifier si n'est pas , ajouter l'opérateur ! :

if (!substr_count($a, 'are')) {
14
répondu T30 2017-12-21 11:21:22

peut-être que vous pourriez utiliser quelque chose comme ça:

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

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

N'utilisez pas preg_match() si vous voulez seulement vérifier si une chaîne est contenue dans une autre chaîne. Utilisez strpos() ou strstr() à la place car ils seront plus rapides. ( http://in2.php.net/preg_match )

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

vous devez utiliser des opérateurs identiques/pas identiques parce que strpos peut retourner 0 comme valeur d'index. Si vous aimez les opérateurs ternaires, envisagez d'utiliser ce qui suit (semble un peu à l'envers, Je l'admets):

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

si vous voulez vérifier si la chaîne contient plusieurs mots spécifiques, vous pouvez faire:

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

ceci est utile pour éviter le spam lors de l'envoi d'e-mails par exemple.

10
répondu Julien 2016-06-25 19:17:33

La fonction strpos fonctionne très bien, mais si vous voulez le faire case-insensitive vérification d'un mot dans un paragraphe, vous pouvez utiliser le stripos en fonction de PHP .

par exemple,

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

trouver la position de la première occurrence d'un substrat insensible à la casse dans une chaîne.

Si le mot n'existe pas dans la chaîne puis il retournera false sinon elle retourne la position de la parole.

9
répondu Akshay Khale 2017-01-05 14:16:57

Vérifier si la chaîne contient des mots spécifiques?

cela signifie que la chaîne doit être résolue en mots (voir la note ci-dessous).

une façon de procéder et de spécifier les séparateurs est d'utiliser 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');

?>

Une course donne

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

Note: symbole.

une définition pratique de mot est dans le sens du PCRE regular expression engine, où les mots sont des substrats constitués de caractères de mot seulement, étant séparés par des caractères non-mot.

Un "mot" de caractère est une lettre ou un chiffre ou le caractère de soulignement, c'est-à-dire tout caractère qui peut faire partie d'un " mot "Perl. Le la définition des lettres et des chiffres est contrôlée par le caractère de PCRE les tables, et peut varier les paramètres régionaux de correspondance (..)

8
répondu mvw 2015-09-23 23:37:08

une chaîne peut être vérifiée avec la fonction suivante:

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