Domanda Come posso verificare se una stringa contiene una parola specifica?


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')?


2668


origine


risposte:


Puoi usare il strpos() funzione che viene 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 è intenzionale; strpos() restituisce l'offset a cui inizia la stringa dell'ago nella stringa del pagliaio o il 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').


5433



È possibile utilizzare le espressioni regolari, è meglio per la corrispondenza delle parole rispetto agli strpos, come menzionato da altri utenti, ma restituirà anche true per le stringhe come tariffa, cura, fissa ecc. Questo può essere semplicemente evitato nell'espressione regolare usando i limiti delle parole.

Una semplice corrispondenza potrebbe essere simile a questa:

$a = 'How are you?';

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

Per quanto riguarda le prestazioni, lo strpos è circa tre volte più veloce e ha in mente, quando ho fatto un milione di confronti contemporaneamente, ci sono voluti 1,5 secondi per completare il trag e per le ottiche ci sono voluti 0,5 secondi.


450



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;
}

195



Mentre la maggior parte di queste risposte ti dirà se una sottostringa appare nella tua stringa, di solito non è quello che vuoi se stai cercando un particolare parolae non a sottostringa.

Qual è la differenza? Le sottostringhe possono apparire in altre parole:

  • I "sono" all'inizio di "area"
  • I "sono" alla fine di "lepre"
  • Il "sono" nel mezzo di "tariffe"

Un modo per mitigare questo sarebbe usare un'espressione regolare accoppiato con confini 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 riportati, ma ha alcuni casi limite. I contorni di parole corrispondono a caratteri non di parole (\W), che sarà tutto ciò che non lo è a-z, A-Z, 0-9, o _. Ciò significa che cifre e caratteri di sottolineatura verranno contati come caratteri di parole e scenari come questo non funzioneranno:

  • Le "sono" in "Cosa stai pensando?"
  • I "sono" in "non lo so, quelli sono4?"

Se vuoi qualcosa di più accurato di questo, dovrai iniziare a fare l'analisi della sintassi della lingua inglese, e questo è un grosso potenziale di worm (e presuppone comunque un uso corretto della sintassi, che non è sempre un dato).


113



Per determinare se una stringa contiene un'altra stringa puoi usare 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 si trova all'inizio del pagliaio, restituirà la posizione 0, se lo fai == confronta che non funzionerà, dovrai farlo a ===

UN == il 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 ANDavere lo stesso tipo - vale a dire entrambe sono stringhe o entrambi sono numeri interi.


92



utilizzando strstr() o stristr() se la tua ricerca dovesse essere insensibile alle maiuscole e alle minuscole sarebbe un'altra opzione.


57



Guarda a strpos():

<?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.";
    }
?>

55



Se si desidera evitare il problema "falso" e "verità", è possibile utilizzare substr_count:

if (substr_count($a, 'are') > 0) {
    echo "at least one 'are' is present!";
}

È un po 'più lento di un puntatore ma evita i problemi di confronto.


37



Utilizzare case-insensitve matching utilizzando stripos():

if (stripos($string,$stringToSearch) !== false) {
    echo 'true';
}

37



Peer to SamGoody e Lego Stormtroopr commenta.

Se stai cercando un algoritmo PHP per classifica i risultati della ricerca in base alla prossimità / rilevanza di più parole ecco un modo semplice e veloce per generare risultati di ricerca solo con PHP:

Problemi con gli altri metodi di ricerca booleani come strpos(), preg_match(), strstr() o stristr() 

  1. non è possibile cercare più parole
  2. i risultati non sono classificati

Metodo PHP basato su Modello spaziale vettoriale e tf-idf (frequenza del documento inversa frequenza del termine):

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 rappresentativi della stringa nel suo insieme, potremmo ordinare i nostri risultati da quelli che corrispondono meglio alla domanda.

Questa è l'idea del modello spaziale vettoriale, non lontano da come funziona la ricerca full-text di 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 molti miglioramenti da apportare ma il modello fornisce un modo per ottenere buoni risultati da domande naturali, che non hanno operatori booleani come strpos(), preg_match(), strstr() o stristr().

NOTA BENE

Opzionalmente eliminando la ridondanza prima di cercare le parole

  • riducendo così la dimensione dell'indice e riducendo i requisiti di stoccaggio

  • meno I / O su disco

  • indicizzazione più veloce e una ricerca di conseguenza più veloce.

1. Normalizzazione

  • Converti tutto il testo in minuscolo

2. Eliminazione delle parole chiave

  • Elimina le parole dal testo che non hanno alcun significato reale (come 'e', ​​'o', 'il', 'per', ecc.)

3. Sostituzione del dizionario

  • Sostituisci le parole con altre che hanno un significato identico o simile. (es: sostituire le istanze di "affamato" e "affamato" 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 


35



Un'altra opzione è usare il strstr () funzione. Qualcosa di simile a:

if (strlen(strstr($haystack,$needle))>0) {
// Needle Found
}

Punto da notare: la funzione strstr () è case-sensitive. Per una ricerca senza distinzione tra maiuscole e minuscole, utilizzare stristr () funzione.


30