stringhe - verificare la presenza di un carattere in una stringa php




Come posso verificare se una stringa contiene una parola specifica? (20)

Controlla se la stringa contiene parole specifiche?

Ciò significa che la stringa deve essere risolta in parole (vedi nota sotto).

Un modo per farlo 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 la parola per ogni sequenza di simboli.

Una definizione pratica di parola è nel senso il motore di espressione regolare PCRE, in cui le parole sono sottostringhe costituite solo da caratteri di parole, separate da caratteri non di parole.

Un carattere "parola" è qualsiasi lettera o cifra o il carattere di sottolineatura, cioè 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 in caso di corrispondenza specifica della lingua (..)

Tenere conto:

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


È necessario utilizzare operatori identici / non identici poiché lo 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';

Dovresti usare il formato Case-Insensitive, quindi se il valore inserito è small o caps non importa.

<?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 stripos trova l'ago nel pagliaio senza considerare il caso (piccolo / caps).

Esempio PHPCode con output


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

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

Ho avuto qualche problema con questo, e alla fine ho scelto di creare la mia soluzione. Senza usare il motore di 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;
 }

Si può notare che le soluzioni precedenti non sono una risposta per la parola utilizzata come prefisso per un'altra. Per utilizzare il tuo esempio:

$a = 'How are you?';
$b = "a skirt that flares from the waist";
$c = "are";

Con gli esempi sopra, sia $a che $b contengono $c , ma potresti volere che la tua funzione ti dica che solo $a contiene $c .


La funzione seguente funziona anche e non dipende da altre funzioni; usa solo la manipolazione nativa della stringa 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 

La funzione strS funziona bene, ma se si desidera eseguire il controllo senza case-insensitive per una parola in un paragrafo, è possibile utilizzare la funzione stripos 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.


Mentre la maggior parte di queste risposte ti dirà se una sottostringa appare nella tua stringa, di solito non è ciò che vuoi se stai cercando una parola particolare, e non una 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 accoppiata con i limiti delle 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 saranno qualsiasi cosa che non sia az , AZ , 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).


Molte risposte che usano substr_count controlla se il risultato è >0 . Ma dal momento che l'istruzione if considera zero uguale a false , puoi evitare di controllare e scrivere direttamente:

if (substr_count($a, 'are')) {

Per verificare se non è presente, aggiungere il ! operatore:

if (!substr_count($a, 'are')) {

Peer to SamGoody e Lego Stormtroopr commenta.

Se stai cercando un algoritmo PHP per classificare i risultati di ricerca in base alla prossimità / rilevanza di più parole, ecco un modo semplice e veloce di 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 Vector Space Model e tf-idf (frequenza dei documenti inversa frequenza-frequenza):

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 complesso, potremmo ordinare i nostri risultati con quelli che corrispondono meglio alla query.

Questa è l'idea del modello di spazio 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 dalle query 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


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 fai un == confronto 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è entrambe sono stringhe o entrambe sono numeri interi.


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
 }

Puoi usare la funzione strpos() che è usata 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 con 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') .


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.


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

Questo è utile per evitare lo spam durante l'invio di e-mail, ad esempio.


Un'altra opzione è usare la funzione strstr() . 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 la funzione stristr() .


Un'altra opzione per trovare l'occorrenza di una parola da una stringa usando strstr() e stristr() è come la seguente:

<?php
    $a = 'How are you?';
    if (strstr($a,'are'))  // Case sensitive
        echo 'true';
    if (stristr($a,'are'))  // Case insensitive
        echo 'true';
?>

Usare strstr() o stristr() se la ricerca dovrebbe essere insensibile alle maiuscole / minuscole sarebbe un'altra opzione.


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




string-matching