Considérer:
$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'instruction if ($a contains 'are')
?
Vous pouvez utiliser la strpos()
fonction utilisée pour rechercher 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 ( != false
ni === true
ne retournera le résultat souhaité); strpos()
renvoie soit l'offset auquel la chaîne d'aiguille commence dans la chaîne de botte de foin, soit le booléen false
si l'aiguille n'est pas trouvée. Puisque 0 est un décalage valide et 0 est "falsey", nous ne pouvons pas utiliser des constructions plus simples comme !strpos($a, 'are')
.
strpos($a, 'are') > -1
pour tester true. Du point de vue du débogage, je trouve que mon cerveau gaspille moins de cycles d'horloge pour déterminer si la ligne est écrite correctement quand je n'ai pas à compter les signes égaux contigus.Vous pouvez utiliser des expressions régulières, c'est mieux pour la correspondance de mots
strpos
que comme mentionné par d'autres utilisateurs, cela retournera également vrai pour les chaînes telles que le tarif, le soin, le regard, etc. Cela peut simplement être évité dans l'expression régulière en utilisant des limites de mots.Une simple correspondance pour are pourrait ressembler à ceci:
Du côté des performances,
strpos
c'est environ trois fois plus rapide et j'ai en tête, quand j'ai fait un million de comparaisons à la fois, il a fallupreg_match
1,5 seconde pour terminer et pourstrpos
cela a pris 0,5 seconde.Edit: afin de rechercher n'importe quelle partie de la chaîne, pas seulement mot par mot, je recommanderais d'utiliser une expression régulière comme
À
i
la fin de l'expression régulière, l'expression régulière est insensible à la casse, si vous ne le souhaitez pas, vous pouvez la laisser de côté.Maintenant, cela peut être assez problématique dans certains cas car la chaîne de recherche $ n'est pas nettoyée de quelque façon que ce soit, je veux dire, elle peut ne pas passer la vérification dans certains cas comme s'il s'agissait d'
$search
une entrée utilisateur, ils peuvent ajouter une chaîne qui pourrait se comporter comme une expression régulière différente ...En outre, voici 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 pouvez utiliser quelque chose comme ceci:
la source
Voici une petite fonction utilitaire qui est utile dans des situations comme celle-ci
la source
if ($email->contains("@") && $email->endsWith(".com)) { ...
ouif (strpos($email, "@") !== false && substr($email, -strlen(".com")) == ".com") { ...
Bien que la plupart de ces réponses vous diront si une sous-chaîne apparaît dans votre chaîne, ce n'est généralement pas ce que vous voulez si vous recherchez un mot particulier , et non une sous - chaîne .
Quelle est la différence? Les sous-chaînes peuvent apparaître entre d'autres mots:
Une façon d'atténuer cela serait d'utiliser une expression régulière couplée à des limites de mots (
\b
):Cette méthode n'a pas les mêmes faux positifs mentionnés ci-dessus, mais elle a ses propres cas limites. Limites correspondent mot sur les caractères non-mot (
\W
), qui vont être quelque chose qui n'est pasa-z
,A-Z
,0-9
ou_
. Cela signifie que les chiffres et les traits de soulignement seront comptés comme des caractères de mot et que des scénarios comme celui-ci échoueront:Si vous voulez quelque chose de plus précis que cela, vous devrez commencer à analyser la syntaxe en anglais, et c'est une très grosse boîte de vers (et suppose une utilisation correcte de la syntaxe, de toute façon, ce qui n'est pas toujours une donnée).
la source
\b
correspond à deux choses qui\W
ne le font pas, ce qui le rend idéal pour trouver des mots dans une chaîne: il correspond au début de la chaîne (^
) et à la fin de la chaîne ($
)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 ] )
MISE EN GARDE:
Si l'aiguille que vous recherchez se trouve au début de la botte de foin, elle retournera en position 0, si vous faites une
==
comparaison qui ne fonctionnera pas, vous devrez faire un===
Un
==
signe est une comparaison et teste si la variable / expression / constante à gauche a la même valeur que la variable / expression / constante à droite.Un
===
signe est une comparaison pour voir si deux variables / expressions / constantes sont égalesAND
ont le même type - c'est-à-dire que les deux sont des chaînes ou les deux sont des entiers.la source
Regardez
strpos()
:la source
Utiliser
strstr()
oustristr()
si votre recherche doit être insensible à la casse serait une autre option.la source
strstr($a, 'are')
est beaucoup plus élégant que le laidstrpos($a, 'are') !== false
. PHP a vraiment besoin d'unestr_contains()
fonction.Utilisez la correspondance insensible à la casse en utilisant
stripos()
:la source
Regardez les commentaires de SamGoody et Lego Stormtroopr.
Si vous recherchez un algorithme PHP pour classer les résultats de recherche en fonction de la proximité / pertinence de plusieurs mots, voici un moyen rapide et facile de générer des résultats de recherche avec PHP uniquement:
Problèmes avec les autres méthodes de recherche booléenne tels que
strpos()
,preg_match()
,strstr()
oustristr()
Méthode PHP basée sur le modèle d'espace vectoriel et tf-idf (terme fréquence – fréquence du document inverse):
Cela semble difficile mais étonnamment facile.
Si nous voulons rechercher plusieurs mots dans une chaîne, le problème principal est de savoir 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 classer nos résultats par ceux qui correspondent le mieux à la requête.
C'est l'idée du modèle d'espace vectoriel, non loin du fonctionnement de la recherche SQL en texte intégral:
CAS 1
RÉSULTAT
CAS 2
RÉSULTATS
CAS 3
RÉSULTATS
Il y a beaucoup d'améliorations à apporter , mais le modèle offre un moyen d'obtenir de bons résultats des requêtes naturelles, qui ne sont pas des opérateurs booléens tels que
strpos()
,preg_match()
,strstr()
oustristr()
.NOTA BENE
Éliminer éventuellement la redondance avant de rechercher les mots
réduisant ainsi la taille de l'index et entraînant moins de stockage
moins d'E / S disque
indexation plus rapide et recherche par conséquent plus rapide.
1. Normalisation
2. Élimination des mots vides
3. Substitution de dictionnaire
Remplacez les mots par d'autres qui ont une signification identique ou similaire. (ex: remplacer les cas de «faim» et «faim» par «faim»)
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 couleurs par leurs équivalents hexadécimaux
La réduction des valeurs numériques en réduisant la précision sont d'autres moyens de normaliser le texte.
RESSOURCES
la source
Si vous voulez éviter le problème "falsey" et "truey", vous pouvez utiliser substr_count:
C'est un peu plus lent que strpos mais ça évite les problèmes de comparaison.
la source
false
pour "êtes-vous sûr?" puisque le postestrpos
est0
Une autre option consiste à utiliser la fonction strstr () . Quelque chose comme:
Point à noter: la fonction strstr () est sensible à la casse. Pour une recherche non sensible à la casse, utilisez la fonction stristr () .
la source
la source
WARNING preg_match(): Delimiter must not be alphanumeric or backslash
Je suis un peu impressionné qu'aucune des réponses ici qui a utilisé
strpos
,strstr
et des fonctions similaires mentionné Fonctions Multibyte Chaîne encore (08/05/2015).Fondamentalement, si vous rencontrez des difficultés pour 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 voudrez peut-être précéder les fonctions avec
mb_
. Par conséquent, la réponse acceptée utiliseraitmb_strpos
oumb_stripos
(pour une correspondance insensible à la casse) à la place:Si vous ne pouvez pas garantir que toutes vos données sont à 100% en UTF-8 , vous pouvez utiliser les
mb_
fonctions.Un bon article pour comprendre pourquoi est le minimum absolu que tout développeur de logiciels doit absolument, positivement, connaître sur l'Unicode et les jeux de caractères (sans excuses!) Par Joel Spolsky .
la source
En PHP, la meilleure façon de vérifier si une chaîne contient une certaine sous-chaîne, est d'utiliser une simple fonction d'aide comme celle-ci:
Explication:
strpos
recherche la position de la première occurrence d'une sous-chaîne sensible à la casse dans une chaîne.stripos
recherche la position de la première occurrence d'une sous-chaîne insensible à la casse dans une chaîne.myFunction($haystack, $needle) === FALSE ? FALSE : TRUE
garantit quemyFunction
renvoie toujours un booléen et corrige un comportement inattendu lorsque l'index de la sous-chaîne est 0.$caseSensitive ? A : B
sélectionne soitstrpos
oustripos
pour effectuer le travail, selon la valeur de$caseSensitive
.Production:
la source
La fonction ci-dessous fonctionne également et ne dépend d'aucune autre fonction; il utilise uniquement la manipulation de chaînes PHP native. Personnellement, je ne recommande pas cela, mais vous pouvez voir comment cela fonctionne:
Tester:
la source
Vous pouvez utiliser la
strstr
fonction:Sans utiliser de fonction intégrée:
la source
J'ai eu quelques problèmes avec cela et j'ai finalement choisi de créer ma propre solution. Sans utiliser le moteur d' expression régulière :
Vous pouvez remarquer que les solutions précédentes ne sont pas une réponse pour le mot utilisé comme préfixe pour un autre. Pour utiliser votre exemple:
Avec les exemples ci-dessus, les deux
$a
et$b
contient$c
, mais vous voudrez peut-être que votre fonction vous dise que$a
contient uniquement$c
.la source
$found = false
au débutUne autre option pour rechercher l'occurrence d'un mot dans une chaîne à l'aide de strstr () et stristr () est la suivante:
la source
i
enstristr
signifie insensible.Beaucoup de réponses qui utilisent des
substr_count
contrôles si le résultat est>0
. Mais comme l'if
instruction considère zéro comme étant faux , vous pouvez éviter cette vérification et écrire directement:Pour vérifier s'il n'est pas présent, ajoutez l'
!
opérateur:la source
Cela peut se faire de trois manières différentes:
1- stristr ()
2- strpos ()
3- preg_match ()
la source
La version courte
la source
Afin de trouver un «mot», plutôt que l'occurrence d'une série de lettres qui pourraient en fait faire partie d'un autre mot, ce qui suit serait une bonne solution.
la source
$string
c'estAre are, are?
Vous devez utiliser un format insensible à la casse, donc si la valeur entrée est
small
ou sicaps
cela n'a pas d'importance.Ici, stripos trouve une aiguille dans une meule de foin sans considérer le cas (petit / casquettes).
Échantillon PHPCode avec sortie
la source
Vous pourriez peut-être utiliser quelque chose comme ceci:
la source
Ne pas utiliser
preg_match()
si vous souhaitez uniquement vérifier si une chaîne est contenue dans une autre chaîne. Utilisezstrpos()
ou à lastrstr()
place car ils seront plus rapides. ( http://in2.php.net/preg_match )la source
Si vous voulez vérifier si la chaîne contient plusieurs mots spécifiques, vous pouvez faire:
C'est utile pour éviter le spam lors de l'envoi d'emails par exemple.
la source
La fonction strpos fonctionne bien, mais si vous voulez
case-insensitive
vérifier un mot dans un paragraphe, vous pouvez utiliser lastripos
fonction dePHP
.Par exemple,
Trouvez la position de la première occurrence d'une sous-chaîne insensible à la casse dans une chaîne.
Si le mot n'existe pas dans la chaîne, il retournera false sinon il renverra la position du mot.
la source
Vous devez utiliser des opérateurs identiques / non identiques car strpos peut renvoyer 0 comme valeur d'index. Si vous aimez les opérateurs ternaires, pensez à utiliser ce qui suit (semble un peu en arrière, je l'admets):
la source
Cela signifie que la chaîne doit être résolue en mots (voir la note ci-dessous).
Une façon de le faire et de spécifier les séparateurs utilise
preg_split
( doc ):Une course donne
Remarque: Ici, nous ne voulons pas dire mot pour chaque séquence de symboles.
Une définition pratique du mot est en ce sens que le moteur d'expression régulière PCRE, où les mots sont des sous-chaînes constituées uniquement de caractères de mot, étant séparés par des caractères non-mot.
la source
Une autre solution pour une chaîne spécifique:
Vous pouvez également utiliser la
strpos()
fonction.la source