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')
?
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')
.
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.
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;
}
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).
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.
<?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.";
}
?>
utilisant strstr()
ou stristr()
si votre recherche devrait être insensible à la casse serait une autre option.
utiliser case-insensitve matching utiliser stripos()
:
if (stripos($string,$stringToSearch) !== false) {
echo 'true';
}
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.
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()
- impossible de rechercher plusieurs mots
- 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
- http://linuxgazette.net/164/sephton.html
- http://snowball.tartarus.org /
- Recherche Fulltext MySQL Score Expliqué
- http://dev.mysql.com/doc/internals/en/full-text-search.html
- http://en.wikipedia.org/wiki/Vector_space_model
- http://en.wikipedia.org/wiki/Tf%E2%80%93idf
- http://phpir.com/simple-search-the-vector-space-model /
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() .
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 .
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
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
.
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 ";
}
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 quemyFunction
renvoie toujours un booléen et fixe un comportement inattendu lorsque l'indice de la chaîne est 0. -
$caseSensitive ? A : B
sélectionnestrpos
oustripos
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)
la version courte
$result = false!==strpos($a, 'are');
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';
}
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';
?>
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).
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
}
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')) {
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';
}
}
?>
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';
}
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';
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.
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.
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 (..)
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;
}