2653 votes

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 façon correcte d'écrire l'instruction if ($a contains 'are') ?

8085voto

codaddict Points 154968

Maintenant, avec PHP 8, vous pouvez le faire en utilisant str_contains :

if (str_contains('How are you', 'are')) { 
    echo 'true';
}

RFC

Avant PHP 8

Vous pouvez utiliser le strpos() 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 renverra le résultat souhaité) ; strpos() renvoie soit le décalage à partir duquel la chaîne 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 décalage valide et que 0 est "faux", nous ne pouvons pas utiliser des constructions plus simples comme !strpos($a, 'are') .

181 votes

@DTest - Oui, bien sûr, il retournera vrai parce que la chaîne contient 'are'. Si vous recherchez spécifiquement le mot ARE, vous devrez effectuer d'autres vérifications comme, par exemple, vérifier s'il y a un caractère ou un espace avant le A et après le E.

47 votes

Très bons commentaires ci-dessus ! Je n'utilise jamais != ou ==, après tout !== et === est la meilleure option (à mon avis) tous les aspects considérés (vitesse, précision etc).

11 votes

@jsherk Pourquoi pas des regex, alors ? Quelque chose comme " sont ".

757voto

Breezer Points 4203

Vous pouvez utiliser des expressions régulières, car elles sont plus adaptées à la correspondance de mots que les expressions régulières. strpos comme l'ont mentionné d'autres utilisateurs. A strpos vérifier are retournera également vrai pour les chaînes de caractères telles que : fare, care, stare, etc. Ces correspondances involontaires peuvent simplement être évitées dans les expressions régulières en utilisant les limites de mots.

Une simple correspondance pour are pourrait ressembler à quelque chose comme ça :

$a = 'How are you?';

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

Du côté des performances, strpos est environ trois fois plus rapide. Quand je faisais un million de comparaisons en même temps, cela prenait preg_match 1,5 seconde pour terminer et pour strpos ça a pris 0,5 seconde.

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

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

El i à la fin de l'expression régulière rend l'expression régulière insensible à la casse, si vous ne le souhaitez pas, vous pouvez l'omettre.

Maintenant, cela peut être assez problématique dans certains cas car la chaîne de recherche $search n'est pas aseptisée de quelque manière que ce soit, je veux dire, elle pourrait ne pas passer la vérification dans certains cas comme 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

Pour combiner les deux ensembles de fonctionnalités en une seule fonction polyvalente (y compris avec une sensibilité à la casse sélectionnable), vous pourriez 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.
}

Une autre chose à prendre en compte, c'est que \b ne fonctionnera pas dans les langues autres que l'anglais.

L'explication de ce problème et la solution sont tirées d'ici :

\b représente le début ou la fin d'un mot (Word Boundary). Cette regex correspondrait à pomme dans tarte aux pommes, mais ne correspondrait pas à pomme dans dans les ananas, les paniers de pommes ou les pommes à cuire.

Pourquoi pas "café" ? Comment extraire le mot "café" en regex ? En fait, \bcaf é \b ne fonctionnerait pas. Pourquoi ? Parce que "café" contient un caractère non ASCII : é. \b ne peut pas être simplement utilisé avec des Unicode tels que समुद्र, 감사, месяц et

1 votes

J'en doute. La documentation indique int preg_match ( string $pattern , string $subject [, array &$matches [, int $flags = 0 [, int $offset = 0 ]]] ) .

1 votes

Je dirais que je trouve que c'est tout le contraire, c'est mauvais de l'utiliser pour des opérations compliquées si une alternative est présente, mais pour une correspondance de mots vraiment simple, c'est génial, vous pouvez définir différents délimiteurs pour ne pas tenir compte de la casse et ainsi de suite.

11 votes

@Alexander.Plutov deuxièmement, vous me donnez un -1 et pas la question ? Allez, ça prend 2 secondes pour trouver la réponse sur Google. google.com/

304voto

ejunker Points 3442

Voici une petite fonction utilitaire 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;
}

1 votes

Il pourrait être à sa place en tant que classe utilitaire et améliorerait la lisibilité.

75 votes

@RobinvanBaalen En fait, cela peut améliorer la lisibilité du code. De plus, les downvotes sont censés être pour les (très) mauvaises réponses, pas pour les réponses "neutres".

1 votes

@Xaqq À mon avis, il est très mauvais d'écrire des fonctions qui ne font rien d'autre qu'améliorer la lisibilité. D'où le -1.

264voto

Milan Babuškov Points 20423

Utilisez strpos fonction :

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

180voto

Jose Vega Points 4791

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, elle retournera la position 0, si vous faites un == comparer qui ne fonctionnera pas, vous devrez faire une ===

A == Le signe est une comparaison et teste si la variable / expression / constante à gauche a la même valeur que la variable / expression / constante à droite.

A === Le signe est une comparaison pour voir si deux variables / expressions / constantes sont égales. AND ont le même type - c'est-à-dire que les deux sont des chaînes de caractères ou des entiers.

0 votes

Si j'utilise "care", il renvoie également vrai :(

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X