Prendere in considerazione:
$a = 'How are you?';
if ($a contains 'are')
echo 'true';
Supponiamo di avere il codice sopra, qual è il modo corretto di scrivere la dichiarazione if ($a contains 'are')
?
Prendere in considerazione:
$a = 'How are you?';
if ($a contains 'are')
echo 'true';
Supponiamo di avere il codice sopra, qual è il modo corretto di scrivere la dichiarazione if ($a contains 'are')
?
Risposte:
È possibile utilizzare la strpos()
funzione utilizzata per trovare l'occorrenza di una stringa all'interno di un'altra:
$a = 'How are you?';
if (strpos($a, 'are') !== false) {
echo 'true';
}
Si noti che l'uso di !== false
è deliberato (né != false
né === true
restituirà il risultato desiderato); strpos()
restituisce l'offset in corrispondenza del quale inizia la stringa dell'ago nella stringa del pagliaio o il valore booleano false
se l'ago non viene trovato. Poiché 0 è un offset valido e 0 è "falsey", non possiamo usare costrutti più semplici come !strpos($a, 'are')
.
strpos($a, 'are') > -1
per verificare la verità. Dal punto di vista del debug, trovo che il mio cervello spreca meno cicli di clock per determinare se la linea è scritta correttamente quando non devo contare segni di uguali contigui.
Potresti usare espressioni regolari, è meglio per la corrispondenza delle parole rispetto a strpos
quanto menzionato da altri utenti, inoltre tornerà vero per stringhe come tariffa, cura, sguardo, ecc. Questo può essere semplicemente evitato nell'espressione regolare usando i confini delle parole.
Una semplice corrispondenza per are potrebbe essere simile a questa:
$a = 'How are you?';
if (preg_match('/\bare\b/', $a)) {
echo 'true';
}
Per quanto riguarda le prestazioni, strpos
è circa tre volte più veloce e ho in mente, quando ho fatto un milione di confronti alla volta, ci sono voluti preg_match
1,5 secondi per terminare e per strpos
0,5 secondi.
Modifica: per cercare qualsiasi parte della stringa, non solo parola per parola, consiglierei di usare un'espressione regolare come
$a = 'How are you?';
$search = 'are y';
if(preg_match("/{$search}/i", $a)) {
echo 'true';
}
La i
fine dell'espressione regolare cambia l'espressione regolare in distinzione tra maiuscole e minuscole, se non lo desideri, puoi lasciarla fuori.
Ora, questo può essere abbastanza problematico in alcuni casi poiché la stringa $ search non è disinfettata in alcun modo, voglio dire, in alcuni casi potrebbe non passare il controllo come se $search
un input dell'utente potesse aggiungere una stringa che potrebbe comportarsi come qualche diversa espressione regolare ...
Inoltre, ecco un ottimo strumento per testare e vedere le spiegazioni di varie espressioni regolari Regex101
Per combinare entrambi i set di funzionalità in un'unica funzione multiuso (incluso con la distinzione maiuscole / minuscole selezionabile), è possibile utilizzare qualcosa del genere:
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.
}
Ecco una piccola funzione di utilità che è utile in situazioni come questa
// returns true if $needle is a substring of $haystack
function contains($needle, $haystack)
{
return strpos($haystack, $needle) !== false;
}
if ($email->contains("@") && $email->endsWith(".com)) { ...
oppureif (strpos($email, "@") !== false && substr($email, -strlen(".com")) == ".com") { ...
Mentre la maggior parte di queste risposte ti dirà se appare una sottostringa nella tua stringa, di solito non è quello che vuoi se stai cercando una parola particolare , e non una sottostringa .
Qual è la differenza? Le sottostringhe possono apparire in altre parole:
Un modo per mitigare questo sarebbe usare un'espressione regolare unita a limiti di parole ( \b
):
function containsWord($str, $word)
{
return !!preg_match('#\\b' . preg_quote($word, '#') . '\\b#i', $str);
}
Questo metodo non ha gli stessi falsi positivi sopra menzionati, ma ha alcuni casi limite propri. Limiti delle parole corrispondono a caratteri non-parola ( \W
), che stanno per essere tutto ciò che non è a-z
, A-Z
, 0-9
, o _
. Ciò significa che le cifre e i trattini bassi verranno conteggiati come caratteri di parole e scenari come questo falliranno:
Se vuoi qualcosa di più preciso di questo, dovrai iniziare a eseguire l'analisi della sintassi in lingua inglese, e questa è una lattina abbastanza grande di worm (e presuppone comunque un uso corretto della sintassi, che non è sempre scontato).
\b
corrisponde a due cose che \W
non lo fanno, il che lo rende ^
$
Per determinare se una stringa contiene un'altra stringa è possibile utilizzare la funzione 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";
}
?>
ATTENZIONE:
Se l'ago che stai cercando è all'inizio del pagliaio, tornerà in posizione 0, se fai un ==
confronto che non funzionerà, dovrai fare un===
Un ==
segno è un confronto e verifica se la variabile / espressione / costante a sinistra ha lo stesso valore della variabile / espressione / costante a destra.
Un ===
segno è un confronto per vedere se due variabili / espressioni / costanti sono uguali AND
hanno lo stesso tipo - cioè entrambi sono stringhe o entrambi sono numeri interi.
<?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.";
}
?>
Utilizzare strstr()
o stristr()
se la ricerca non dovrebbe fare distinzione tra maiuscole e minuscole sarebbe un'altra opzione.
strstr($a, 'are')
è molto più elegante dei brutti strpos($a, 'are') !== false
. PHP ha davvero bisogno di una str_contains()
funzione.
Utilizza la corrispondenza senza distinzione tra maiuscole e minuscole utilizzando stripos()
:
if (stripos($string,$stringToSearch) !== false) {
echo 'true';
}
Scrutiamo i commenti di SamGoody e Lego Stormtroopr.
Se stai cercando un algoritmo PHP per classificare i risultati della ricerca in base alla prossimità / rilevanza di più parole, ecco un modo rapido e semplice di generare risultati di ricerca solo con PHP:
Problemi con gli altri metodi di ricerca booleana, come strpos()
, preg_match()
, strstr()
ostristr()
Metodo PHP basato su Vector Space Model e tf-idf (termine frequenza-frequenza inversa del documento):
Sembra difficile ma è sorprendentemente facile.
Se vogliamo cercare più parole in una stringa, il problema principale è come assegniamo un peso a ciascuna di esse?
Se potessimo ponderare i termini in una stringa in base a quanto siano rappresentativi della stringa nel suo insieme, potremmo ordinare i nostri risultati in base a quelli che meglio corrispondono alla query.
Questa è l'idea del modello dello spazio vettoriale, non lontano da come funziona la ricerca full-text SQL:
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;
}
CASO 1
$query = 'are';
$corpus = array(
1 => 'How are you?',
);
$match_results=get_similar_documents($query,$corpus);
echo '<pre>';
print_r($match_results);
echo '</pre>';
RISULTATO
Array
(
[1] => 0.52832083357372
)
CASO 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>';
RISULTATI
Array
(
[1] => 0.54248125036058
[3] => 0.21699250014423
)
CASO 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>';
RISULTATI
Array
(
[3] => 0.6813781191217
[1] => 0.54248125036058
)
Ci sono un sacco di miglioramenti da apportare, ma il modello fornisce un modo di ottenere buoni risultati da query naturali, che non hanno operatori booleani quali strpos()
, preg_match()
, strstr()
o stristr()
.
NOTA BENE
Eliminazione facoltativa della ridondanza prima di cercare le parole
riducendo così le dimensioni dell'indice e riducendo i requisiti di archiviazione
meno I / O su disco
indicizzazione più rapida e una ricerca di conseguenza più veloce.
1. Normalizzazione
2. Eliminazione di Stopword
3. Sostituzione del dizionario
Sostituisci le parole con altre che hanno un significato identico o simile. (ad esempio: sostituisci i casi di "fame" e "fame" con "fame")
Ulteriori misure algoritmiche (palla di neve) possono essere eseguite per ridurre ulteriormente le parole al loro significato essenziale.
La sostituzione dei nomi dei colori con i loro equivalenti esadecimali
La riduzione dei valori numerici riducendo la precisione sono altri modi per normalizzare il testo.
RISORSE
Se vuoi evitare il problema "falso" e "vero", puoi usare substr_count:
if (substr_count($a, 'are') > 0) {
echo "at least one 'are' is present!";
}
È un po 'più lento di Strpos ma evita i problemi di confronto.
false
per "sei sicuro?" poiché la posizione per strpos
è0
Un'altra opzione è quella di utilizzare la funzione strstr () . Qualcosa di simile a:
if (strlen(strstr($haystack,$needle))>0) {
// Needle Found
}
Nota: la funzione strstr () fa distinzione tra maiuscole e minuscole. Per una ricerca senza distinzione tra maiuscole e minuscole, utilizzare la funzione stristr () .
Sono un po 'impressionato dal fatto che nessuna delle risposte qui che ha usato strpos
, strstr
e analoghe menzionato Funzioni Multibyte stringa ancora (2015/05/08).
Fondamentalmente, se hai problemi a trovare parole con caratteri specifici di alcune lingue , come tedesco, francese, portoghese, spagnolo, ecc. (Es. Ä , é , ô , ç , º , ñ ), potresti voler precedere le funzioni con mb_
. Pertanto, la risposta accettata utilizza invece mb_strpos
o mb_stripos
(per la corrispondenza senza maiuscole / minuscole):
if (mb_strpos($a,'are') !== false) {
echo 'true';
}
Se non puoi garantire che tutti i tuoi dati siano al 100% in UTF-8 , potresti voler utilizzare le mb_
funzioni.
Un buon articolo per capire il motivo per cui è Developer minima assoluta Ogni software assolutamente, positivamente deve sapere su Unicode e set di caratteri (scuse!) Da Joel Spolsky .
In PHP, il modo migliore per verificare se una stringa contiene una determinata sottostringa è utilizzare una semplice funzione di supporto come questa:
function contains($haystack, $needle, $caseSensitive = false) {
return $caseSensitive ?
(strpos($haystack, $needle) === FALSE ? FALSE : TRUE):
(stripos($haystack, $needle) === FALSE ? FALSE : TRUE);
}
strpos
trova la posizione della prima occorrenza di una sottostringa sensibile al maiuscolo / minuscolo in una stringa.stripos
trova la posizione della prima occorrenza di una sottostringa senza distinzione tra maiuscole e minuscole in una stringa.myFunction($haystack, $needle) === FALSE ? FALSE : TRUE
assicura che myFunction
restituisca sempre un valore booleano e risolve comportamenti imprevisti quando l'indice della sottostringa è 0.$caseSensitive ? A : B
seleziona strpos
o stripos
per eseguire il lavoro, a seconda del valore di $caseSensitive
.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)
Anche la seguente funzione funziona e non dipende da altre funzioni; utilizza solo la manipolazione nativa di stringhe PHP. Personalmente, non lo consiglio, ma puoi vedere come funziona:
<?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;
}
}
Test:
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
Puoi usare la strstr
funzione:
$haystack = "I know programming";
$needle = "know";
$flag = strstr($haystack, $needle);
if ($flag){
echo "true";
}
Senza utilizzare una funzione integrata:
$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 ";
}
Ho avuto qualche problema con questo, e alla fine ho scelto di creare la mia soluzione. Senza usare il motore delle espressioni regolari :
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;
}
È possibile notare che le soluzioni precedenti non sono una risposta per la parola utilizzata come prefisso per un'altra. Per usare il tuo esempio:
$a = 'How are you?';
$b = "a skirt that flares from the waist";
$c = "are";
Con gli esempi sopra, entrambi $a
e $b
contiene $c
, ma potresti volere che la tua funzione ti dica che $a
contiene solo $c
.
$found = false
all'inizio
Un'altra opzione per trovare la ricorrenza di una parola da una stringa usando strstr () e stristr () è simile alla seguente:
<?php
$a = 'How are you?';
if (strstr($a,'are')) // Case sensitive
echo 'true';
if (stristr($a,'are')) // Case insensitive
echo 'true';
?>
i
in stristr
acronimo di insensibile.
Molte risposte che usano i substr_count
controlli se il risultato è >0
. Ma poiché l' if
istruzione considera zero uguale a falso , puoi evitare questo controllo e scrivere direttamente:
if (substr_count($a, 'are')) {
Per verificare se non presente, aggiungere l' !
operatore:
if (!substr_count($a, 'are')) {
Può essere fatto in tre modi diversi:
$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
}
La versione abbreviata
$result = false!==strpos($a, 'are');
Al fine di trovare una "parola", piuttosto che la presenza di una serie di lettere che potrebbero effettivamente far parte di un'altra parola, la seguente sarebbe una buona soluzione.
$string = 'How are you?';
$array = explode(" ", $string);
if (in_array('are', $array) ) {
echo 'Found the word';
}
$string
èAre are, are?
Dovresti usare il formato maiuscole e minuscole, quindi se il valore inserito è small
o caps
non ha importanza.
<?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";
}
?>
Qui lo stripos trova l'ago nel pagliaio senza considerare il caso (piccolo / maiuscolo).
Forse potresti usare qualcosa del genere:
<?php
findWord('Test all OK');
function findWord($text) {
if (strstr($text, 'ok')) {
echo 'Found a word';
}
else
{
echo 'Did not find a word';
}
}
?>
Non utilizzare preg_match()
se si desidera solo verificare se una stringa è contenuta in un'altra stringa. Usa strpos()
o strstr()
invece come saranno più veloci. ( http://in2.php.net/preg_match )
if (strpos($text, 'string_name') !== false){
echo 'get the string';
}
Se vuoi verificare se la stringa contiene diverse parole specifiche, puoi fare:
$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";
}
Ciò è utile per evitare spam, ad esempio quando si inviano e-mail.
La funzione strpos funziona benissimo, ma se si desidera eseguire il case-insensitive
controllo di una parola in un paragrafo, è possibile utilizzare la stripos
funzione di PHP
.
Per esempio,
$result = stripos("I love PHP, I love PHP too!", "php");
if ($result === false) {
// Word does not exist
}
else {
// Word exists
}
Trova la posizione della prima occorrenza di una sottostringa senza distinzione tra maiuscole e minuscole in una stringa.
Se la parola non esiste nella stringa, restituirà false altrimenti restituirà la posizione della parola.
È necessario utilizzare operatori identici / non identici perché strpos può restituire 0 come valore di indice. Se ti piacciono gli operatori ternari, considera l'utilizzo di quanto segue (sembra un po 'arretrato, lo ammetto):
echo FALSE === strpos($a,'are') ? 'false': 'true';
Verifica se la stringa contiene parole specifiche?
Questo significa che la stringa deve essere risolta in parole (vedi nota sotto).
Un modo per fare questo e per specificare i separatori sta usando 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');
?>
Una corsa dà
$ 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'
Nota: qui non intendiamo parola per ogni sequenza di simboli.
Una definizione pratica di parola è nel senso che il motore di espressione regolare PCRE, in cui le parole sono sottostringhe costituite solo da caratteri di parole, essendo separate da caratteri non di parole.
Un carattere "parola" è qualsiasi lettera o cifra o il carattere di sottolineatura, ovvero qualsiasi carattere che può far parte di una "parola" Perl. La definizione di lettere e cifre è controllata dalle tabelle dei caratteri di PCRE e può variare se si verifica una corrispondenza specifica della locale (..)