Comment puis-je vérifier si une chaîne contient un mot en particulier?
Considérer:
$a = 'How are you?';
if ($a contains 'are')
echo 'true';
Supposons que j'ai le code ci-dessus, quelle est la bonne manière d'écrire l'instruction if ($a contains 'are')
?
Vous devez vous connecter pour publier un commentaire.
Vous pouvez utiliser le
strpos()
fonction qui est utilisée pour trouver l'occurrence d'une chaîne à l'intérieur d'une autre:Noter que l'utilisation de
!== false
est délibérée;strpos()
retourne l'offset à laquelle l'aiguille début de la chaîne dans la botte de foin de la ficelle ou de la booleanfalse
si l'aiguille n'est pas trouvé. Depuis que 0 est une valeur de décalage et 0 est "falsey", on ne peut pas utiliser plus simple des constructions comme les!strpos($a, 'are')
.if ((strpos($form_email,'@') === false) || (strpos($form_email,'.') === false)) { $error = 'Invalid email<br>'; }
if (strpos($a,'are')!==true) {...}
mais il ne fonctionne pas. Au lieu de cela je me sers maintenant:if(! (strpos($a,'are')!==false)) { ... }
qui a l'air gêné. N'importe qui?strpos($a,'are')===false
.===
est le complémentaire de l'opérateur de!==
.===
) ou sans (==
) type de vérification? Suggérez-vous, que===
est plus rapide que==
? Je doute donc...strpos($a, 'are') > -1
de tester pour de vrai. À partir d'une perspective débogage, j'ai trouver mon cerveau déchets de moins en moins de cycles d'horloge de déterminer si la ligne est écrite correctement lorsque je n'ai pas à compter contiguë signes "égal"." are "
n'est pas la solution, car il n'est pas nécessairement suivi d'un espace (par exemple." You are. "
)if (strpos($a, 'are') > -1) {//found}else{//not found}
$subject = 'How are you?';$query = 'are';if (strpos($subject, $query) !== false)...
. Pas de soucis si pas, le fait qu'il a été vu de 2,5 millions de fois est probablement aussi une bonne raison de ne pas la modifier. Je voudrais aussi opter pourreturn true
plutôt queecho 'true'
mais je comprends que c'est vraiment commencer à s'écarter de la question.str_contains($a, 'are');
comme on le voit ici: laravel.com/docs/5.5/helpers#method-str-contains.grapheme_strpos()
. Ou, si vraiment vous ne pouvez pas utiliser International, utilisezmb_strpos()
à la place.if (strpos($a, 'are') === true)
Vous pouvez utiliser des expressions régulières, c'est mieux pour le mot correspondant par rapport à
strpos
comme mentionné par d'autres utilisateurs, il reviendra également vrai pour les chaînes de caractères comme tarif, de soins, de stare, etc. Cela peut simplement être évitée dans l'expression régulière en utilisant les limites de mot.Un match simple pour le pourrait ressembler à quelque chose comme ceci:
Du côté de la performance,
strpos
est environ trois fois plus vite et avoir à l'esprit, quand j'ai fait un million compare à la fois, il a fallupreg_match
de 1,5 secondes pour terminer et pourstrpos
il a pris de 0,5 secondes.Edit:
Pour la recherche d'une quelconque partie de la chaîne, et pas seulement de mot en mot, je vous conseille d'utiliser une expression régulière comme
La
i
à la fin de l'expression régulière des modifications de l'expression régulière pour être sensible à la casse, si vous ne voulez pas, vous pouvez les laisser.Maintenant, cela peut être très problématique dans certains cas, comme l' $chaîne de recherche n'est pas aseptisé de toute façon, je veux dire, il pourrait ne pas passer le vérifier dans certains cas, comme s'
$search
est une entrée de l'utilisateur, ils peuvent ajouter une chaîne de caractères qui peuvent se comporter comme des exemples de différents expression régulière...Aussi, voici un excellent outil pour tester et voir les explications des différentes expressions régulières Regex101
De combiner les deux ensembles de fonctionnalités dans un seul multi-usage de la fonction (y compris avec une sélection sensible à la casse"), vous pouvez utiliser quelque chose comme ceci:
int preg_match ( string $pattern , string $subject [, array &$matches [, int $flags = 0 [, int $offset = 0 ]]] )
.preg_match
fonctionne lorsque vous avez besoin pour vérifier le résultat dejson
demande (qui ne contient pas deerror
mot?) avantjson_decode
.strpos
ne fonctionne pas pour moi.$a='Computer hardware'
, je veux qu'il reviennefalse
lors de la recherche pourare
. Néanmoins, dans ce cas, elle renvoie la valeur true. Comment faites-vous pour ne recherchez que des mots entiers???'/\bare\b/'
. Le\b
est un marqueur de limite de mot, de sorte que cette expression régulière ne correspond pas 'matériel'.Ici est un peu la fonction d'utilité qui est utile dans des situations de ce genre
if ($email->contains("@") && $email->endsWith(".com)) { ...
ouif (strpos($email, "@") !== false && substr($email, -strlen(".com")) == ".com") { ...
Alors que la plupart de ces réponses pourront vous dire si une sous-chaîne apparaît dans votre chaîne, ce n'est généralement pas ce que vous voulez si vous êtes à la recherche pour un particulier mot, et pas un sous-chaîne.
Quelle est la différence? Les chaînes peuvent apparaître dans d'autres mots:
Une façon d'atténuer ce serait d'utiliser une expression régulière couplée avec les limites de mot (
\b
):Cette méthode n'a pas le même faux positifs indiqué ci-dessus, mais elle a quelques cas de bord de son propre. Les limites de mot de match sur la non-caractères de mot (
\W
), qui vont être quelque chose qui n'est pasa-z
,A-Z
,0-9
, ou_
. Cela signifie que des chiffres et des caractères de soulignement sont va être compté comme la parole des personnages et des scénarios de ce genre de fail:Si vous voulez quelque chose de plus précis que cela, vous avez pour commencer à faire de l'anglais la langue de vérification de syntaxe, et c'est une assez grosse boîte de pandore (et suppose la bonne utilisation de la syntaxe, de toute façon, ce qui n'est pas toujours une donnée).
\b
correspond à deux choses qui\W
ne le fait pas, qui le rend idéal pour trouver mots est une chaîne de caractères: Elle 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 de caractères, vous pouvez utiliser la fonction PHP strpos().
int strpos ( string $haystack , mixed $needle [, int $offset = 0 ] )
ATTENTION:
Si l'aiguille que vous recherchez est au début de la botte de foin, il sera de retour en position 0, si vous faites un
==
comparez cela ne fonctionnera pas, vous aurez besoin de faire un===
Un
==
signe 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.Un
===
signe est une comparaison pour voir si deux variables /expressions /constantes sont égauxAND
ont le même type c'est à dire les deux sont des chaînes de caractères, ou les deux, sont des nombres entiers.Regardez
strpos()
:À l'aide de
strstr()
oustristr()
si votre recherche devrait être sensible à la casse serait une autre option.strstr($a, 'are')
est beaucoup plus élégant que le laidstrpos($a, 'are') !== false
. PHP a vraiment besoin d'unestr_contains()
fonction.Peer to SamGoody et Lego Stormtroopr commentaires.
Si vous êtes à la recherche pour un PHP algorithme de rang des résultats de recherche basés sur la proximité et de la pertinence de plusieurs mots
voici un moyen facile et rapide de générer des résultats de recherche avec PHP seulement:
Questions avec l'autre les méthodes de recherche booléenne comme
strpos()
,preg_match()
,strstr()
oustristr()
PHP méthode basée sur Modèle Vectoriel et tf-idf (term frequency–inverse document frequency):
Il semble difficile mais il est étonnamment facile.
Si nous voulons rechercher plusieurs mots dans une chaîne, le problème central est de savoir comment nous attribuer un poids à chacun d'eux?
Si nous pouvions poids des termes dans une chaîne de caractères basé sur la façon dont ils sont représentatifs 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 vectoriel, non loin de la façon dont SQL de recherche de texte intégral d'œuvres:
CAS 1
RÉSULTAT
CAS 2
RÉSULTATS
CAS 3
RÉSULTATS
Il y a beaucoup d'améliorations à apporter
mais le modèle fournit un moyen d'obtenir de bons résultats naturels des requêtes,
qui n'ont pas les opérateurs booléens tels que
strpos()
,preg_match()
,strstr()
oustristr()
.NOTA BENE
Éventuellement éliminer la redondance avant de rechercher les mots
réduisant ainsi la taille de l'index et résultant en moins de besoins de stockage
moins d'I/O disque
la rapidité d'indexation et, par conséquent, une recherche plus rapide.
1. Normalisation
2. Ignoré élimination
3. Dictionnaire de substitution
Remplacer des mots par d'autres qui ont un produit identique ou similaire sens.
(ex:remplacer les occurrences de "avidement" et "faim" avec la "faim")
Plus d'algorithmique mesures (boule de neige) peuvent être effectuées pour réduire les mots à leur signification essentielle.
Le remplacement des noms de couleur avec leurs équivalents hexadécimaux
La réduction de valeurs numériques en réduisant la précision sont d'autres façons de normaliser le texte.
RESSOURCES
Faire usage de cas insensitve correspondant à l'aide de
stripos()
:Si vous voulez éviter les "falsey" et "truthy" problème, vous pouvez utiliser substr_count:
C'est un peu plus lent que strpos mais évite de la comparaison de problèmes.
Une autre option est d'utiliser le strstr() fonction. Quelque chose comme:
Point à noter: Le strstr() la fonction est sensible à la casse. Pour la casse de la recherche, utilisez la stristr() fonction.
stristr()
Je suis un peu impressionnée par le fait qu'aucune des réponses ici
strpos
,strstr
et des fonctions similaires mentionnés Fonctions De Chaînes De Caractères Multi-Octets encore (2015-05-08).En gros, si vous êtes avoir de la difficulté à trouver des mots avec des caractères spécifiques à certaines langues, comme l'allemand, le français, le portugais, l'espagnol, etc. (par exemple: ä, é, ô, ç, º, ñ), vous pouvez faire précéder les fonctions avec
mb_
. Par conséquent, l'on a accepté la réponse serait d'utilisermb_strpos
oumb_stripos
(comparaison insensible à la casse) à la place:Si vous ne pouvez pas garantir que l'ensemble de vos données est de 100% en UTF-8, vous pouvez utiliser le
mb_
fonctions.Un bon article pour comprendre pourquoi Le Minimum Absolu que Tout Développeur Doit Absolument, Positivement Savoir Sur Unicode et les Jeux de Caractères (Pas d'Excuses!) par Joel Spolsky.
WARNING preg_match(): Delimiter must not be alphanumeric or backslash
La fonction ci-dessous qui fonctionne et ne dépend pas d'une autre fonction; il n'utilise que PHP natif de manipulation de chaîne. Personnellement, je ne recommande pas cela, mais vous pouvez voir comment cela fonctionne:
Test:
En PHP, la meilleure façon de vérifier si une chaîne contient un certain sous-chaîne, est d'utiliser une simple fonction d'assistance comme ceci:
Explication:
strpos
trouve la position de la première occurrence d'un cas sensible à la sous-chaîne dans une chaîne.stripos
trouve la position de la première occurrence d'un casse sous-chaîne dans une chaîne.myFunction($haystack, $needle) === FALSE ? FALSE : TRUE
assure quemyFunction
retourne toujours une valeur booléenne et résout un comportement inattendu lorsque l'index de la sous-chaîne est de 0.$caseSensitive ? A : B
sélectionne soitstrpos
oustripos
pour faire le travail, en fonction de la valeur de$caseSensitive
.De sortie:
J'ai eu quelques difficultés avec cela, et finalement j'ai choisi de créer ma propre solution. Sans l'aide de expression régulière moteur:
Vous pouvez remarquer que les solutions précédentes ne sont pas une réponse pour le mot étant utilisé comme préfixe pour l'autre. Afin d'utiliser votre exemple:
Avec les exemples ci-dessus, les deux
$a
et$b
contient$c
, mais vous pourriez voulez que votre fonction pour vous dire que seuls les$a
contient$c
.$found = false
au débutVous pouvez utiliser le
strstr
fonction:Sans l'aide d'une fonction intégrée de fonction:
Une autre option pour trouver les occurrences d'un mot à partir d'une chaîne à l'aide de strstr() et stristr() est comme suit:
i
dansstristr
signifie insensible.Il peut être fait de trois façons différentes:
1 - stristr()
2 - strpos()
3 - preg_match()
Court-version
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
estAre are, are?
Vous devez utiliser la casse de format,de sorte que si la valeur saisie est en
small
oucaps
il l'habitude de la matière.Ici stripos trouve aiguille dans heystack sans considérant cas (petit/caps).
PHPCode Échantillon avec sortie
$needle = "this";
=> codepad.org/wUIKQ0A8Beaucoup de réponses qui utilisent
substr_count
vérifie si le résultat est>0
. Mais depuis leif
instruction estime zéro le même en tant que faux, vous pouvez éviter que de vérifier et de les écrire directement:Pour vérifier si pas présent, ajoutez l'
!
opérateur:Peut-être vous pouvez utiliser quelque chose comme ceci:
Ne pas utiliser
preg_match()
si vous voulez seulement de vérifier si une chaîne est contenue dans une autre chaîne. Utilisationstrpos()
oustrstr()
au lieu de cela, car ils seront plus rapide. (http://in2.php.net/preg_match)Si vous voulez vérifier si la chaîne contient plusieurs spécificités mots, vous pouvez le faire:
C'est utile pour éviter les spams, lors de l'envoi d'e-mails par exemple.
La fonction strpos fonctionne très bien, mais si vous voulez faire
case-insensitive
la vérification d'un mot dans un paragraphe, vous pouvez faire usage de lastripos
fonction dePHP
.Par exemple,
Trouver la position de la première occurrence de la casse sous-chaîne 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.
Vous devez utiliser identiques ou pas identiques opérateurs parce que strpos peut retourner 0 comme valeur de l'indice. Si vous aimez les opérateurs ternaires, l'utilisation de la suite (il semble un peu en arrière, je l'admets):
Cela signifie que la chaîne doit être résolu en mots (voir la note ci-dessous).
Une façon de le faire et de spécifier le séparateur est à l'aide de
preg_split
(doc):Une course donne
Remarque: Ici on ne parle pas de mot pour chaque séquence de symboles.
Une définition pratique de la parole est dans le sens le moteur d'expression régulière PCRE, où les mots sont des sous-chaînes composé de caractères de mot seulement, étant séparés par des non-caractères de mot.
Une chaîne de caractères peut être vérifié avec le dessous de la fonction:
return strpos($str, $character) !== false
Une autre solution pour une chaîne spécifique:
Vous pouvez également utiliser
strpos()
fonction.Utilisation:
Une option plus simple:
Je pense qu'une bonne idée est d'utiliser
mb_stpos
:Parce que cette solution est sensible à la casse et sans danger pour tous les caractères Unicode.
Mais vous pouvez aussi faire comme ceci (sauch réponse n'était pas encore):
Cette solution est également sensible à la casse et sûr pour les caractères Unicode.
En outre, vous ne pas utiliser la négation de l'expression, qui augmente la lisibilité du code.
Ici est d'autre solution à l'aide de la fonction:
Utilisation:
Il effectue un multi-octets sûr strpos() de l'opération.
mb_strpos(...)
retour à zéro, ce qui évolue dans le faux.Vous pouvez également utiliser les fonctions intégrées
strchr()
etstrrchr()
et des extensions pour les chaînes de caractères multi-octetsmb_strchr()
etmb_strrchr()
.Ces fonctions retournent des parties de cordes, et
FALSE
si rien n'est trouvé.strchr()
- Trouver la première occurrence d'une chaîne (qui est un alias destrstr()
).strrchr()
- Trouver la dernière occurrence d'un caractère dans une chaîne.