Comment vérifier si une chaîne de caractères contient un mot spécifique ?

Pensez-y :

$a = 'How are you?';

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

Supposons que j'ai le code ci-dessus, quelle est la manière correcte d'écrire l'instruction if ($a contains 'are&#39 ;) ?

Solution

Vous pouvez utiliser la fonction [strpos()][1] qui est utilisée pour trouver l'occurrence d'une chaîne de caractères à 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 (ni != false ni === true ne retourneront le résultat souhaité) ; strpos() retourne soit le décalage auquel la chaîne aiguille commence dans la chaîne botte de foin, soit le booléen false si l'aiguille n'est pas trouvée. Puisque 0 est un décalage valide et que 0 est "faux", nous ne pouvons pas utiliser des constructions plus simples comme !strpos($a, 'are').

[1] : http://php.net/manual/en/function.strpos.php

Commentaires (29)

Vous pouvez utiliser les expressions régulières, elles sont plus efficaces pour la correspondance des mots que strpos, comme l'ont mentionné d'autres utilisateurs. Elles renvoient également vrai pour les chaînes de caractères telles que fare, care, stare, etc. Cela peut être simplement évité dans les expressions régulières en utilisant les limites de mots.

Une correspondance simple pour are pourrait ressembler à ceci :

$a = 'How are you?';

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

Du côté des performances, strpos est environ trois fois plus rapide et n'oubliez pas que lorsque j'ai fait un million de comparaisons en une seule fois, il a fallu 1,5 seconde à preg_match pour terminer et 0,5 seconde à strpos.

Modifier : Afin de rechercher n'importe quelle partie de la chaîne, et pas seulement mot par mot, je recommanderais d'utiliser une expression régulière telle que

$a = 'How are you?';
$search = 'are y';
if(preg_match("/{$search}/i", $a)) {
    echo 'true';
}

Le i à la fin de l'expression régulière change l'expression régulière pour être insensible à la casse, si vous ne voulez pas cela, vous pouvez l'omettre.

Maintenant, cela peut être assez problématique dans certains cas car la chaîne $search n'est pas aseptisée de quelque manière que ce soit, je veux dire qu'elle pourrait ne pas passer la vérification dans certains cas car si $search est une entrée utilisateur, ils peuvent ajouter une chaîne qui pourrait se comporter comme une expression régulière différente...

Voici également un excellent outil pour tester et voir les explications de diverses expressions régulières [Regex101][1].

[1] : https://regex101.com/

Pour combiner les deux ensembles de fonctionnalités en une seule fonction polyvalente (y compris avec une sensibilité à la casse sélectionnable), vous pouvez utiliser quelque chose comme ceci :

function FindString($needle,$haystack,$i,$word)
{   // $i should be "" or "i" for case insensitive
    if (strtoupper($word)=="W")
    {   // if $word is "W" then word search instead of string in string search.
        if (preg_match("/\b{$needle}\b/{$i}", $haystack)) 
        {
            return true;
        }
    }
    else
    {
        if(preg_match("/{$needle}/{$i}", $haystack)) 
        {
            return true;
        }
    }
    return false;
    // Put quotes around true and false above to return them as strings instead of as bools/ints.
}
Commentaires (13)

[Regardez strpos()] [1] :

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

[1] : http://php.net/manual/en/function.strpos.php

Commentaires (0)