Pregunta ¿Cómo puedo verificar si una cadena contiene una palabra específica?


Considerar:

$a = 'How are you?';

if ($a contains 'are')
    echo 'true';

Supongamos que tengo el código anterior, ¿cuál es la forma correcta de escribir el enunciado? if ($a contains 'are')?


2668


origen


Respuestas:


Puedes usar el strpos() función que se utiliza para encontrar la ocurrencia de una cadena dentro de otra:

$a = 'How are you?';

if (strpos($a, 'are') !== false) {
    echo 'true';
}

Tenga en cuenta que el uso de !== false es deliberado; strpos() devuelve el desplazamiento en el que comienza la cuerda de la aguja en la cuerda del pajar o la booleana false si la aguja no se encuentra Como 0 es un desplazamiento válido y 0 es "falsey", no podemos usar construcciones más simples como !strpos($a, 'are').


5436



Podrías usar expresiones regulares, es mejor para emparejar palabras en comparación con strpos como lo mencionaron otros usuarios, también volverá a ser verdadero para cadenas tales como tarifa, cuidado, mirada fija, etc. Esto simplemente se puede evitar en la expresión regular usando límites de palabras.

Una simple coincidencia para son podría ser algo como esto:

$a = 'How are you?';

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

Por el lado del rendimiento, Strpos es aproximadamente tres veces más rápido y tenemos en mente que, cuando hice un millón de comparaciones a la vez, tardé 30 segundos en terminar y terminé en 0,5 segundos.


450



Aquí hay una pequeña función de utilidad que es útil en situaciones como esta

// returns true if $needle is a substring of $haystack
function contains($needle, $haystack)
{
    return strpos($haystack, $needle) !== false;
}

195



Si bien la mayoría de estas respuestas le dirán si una subcadena aparece en su cadena, eso no es lo que usted quiere si está buscando una particular palabra, y no un subcadena.

¿Cual es la diferencia? Las subcadenas pueden aparecer dentro de otras palabras:

  • Los "son" al comienzo del "área"
  • Los "son" al final de "liebre"
  • Los "son" en medio de "tarifas"

Una forma de mitigar esto sería usar una expresión regular junto con límites de palabras (\b)

function containsWord($str, $word)
{
    return !!preg_match('#\\b' . preg_quote($word, '#') . '\\b#i', $str);
}

Este método no tiene los mismos falsos positivos indicados anteriormente, pero sí tiene algunos casos propios. Los límites de las palabras coinciden con los caracteres que no son palabras (\W), que van a ser cualquier cosa que no sea a-z, A-Z, 0-9, o _. Eso significa que los dígitos y guiones bajos se contarán como caracteres de palabra y escenarios como este fallarán:

  • Los "son" en "¿Qué estás pensando?"
  • Los "are" en "lol u dunno wut those are4?"

Si quieres algo más preciso que esto, tendrás que comenzar a hacer un análisis de sintaxis en inglés, y esa es una gran cantidad de gusanos (y asume el uso apropiado de la sintaxis, de todos modos, que no siempre es un hecho).


113



Para determinar si una cadena contiene otra cadena, puede usar la función de 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";
}

?>

PRECAUCIÓN:

Si la aguja que está buscando está al principio del pajar, devolverá la posición 0, si hace una == comparar eso no va a funcionar, tendrá que hacer una ===

UN == signo es una comparación y prueba si la variable / expresión / constante a la izquierda tiene el mismo valor que la variable / expresión / constante a la derecha.

UN === signo es una comparación para ver si dos variables / expresiones / constantes son iguales ANDtienen el mismo tipo, es decir, ambos son cadenas o ambos son enteros.


92



Utilizando strstr() o stristr() si su búsqueda no distingue mayúsculas de minúsculas sería otra opción.


57



Mirar 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



Si desea evitar el problema "falsey" y "truthy", puede usar substr_count:

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

Es un poco más lento que strpos, pero evita los problemas de comparación.


37



Hacer uso de coincidencia de mayúsculas y minúsculas utilizando stripos():

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

37



Igual a los comentarios de SamGoody y Lego Stormtroopr.

Si está buscando un algoritmo PHP para resultados de búsqueda de rango basados ​​en proximidad / relevancia de múltiples palabras Aquí viene una forma rápida y fácil de generar resultados de búsqueda con PHP solamente:

Problemas con los otros métodos de búsqueda booleanos como strpos(), preg_match(), strstr() o stristr() 

  1. no puede buscar varias palabras
  2. los resultados no están marcados

Método PHP basado en Modelo de espacio vectorial y tf-idf (frecuencia del término-frecuencia inversa del documento):

Suena difícil pero es sorprendentemente fácil.

Si queremos buscar varias palabras en una cadena, ¿cuál es el problema principal de cómo asignamos un peso a cada una de ellas?

Si pudiéramos ponderar los términos en una cadena en función de lo representativos que sean de la cadena como un todo, podríamos ordenar nuestros resultados por los que mejor coincidan con la consulta.

Esta es la idea del modelo de espacio vectorial, no muy lejos de cómo funciona la búsqueda de texto completo de 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>';

RESULTADO

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

RESULTADOS

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

RESULTADOS

Array
(
    [3] => 0.6813781191217
    [1] => 0.54248125036058
)

Hay muchas mejoras por hacer pero el modelo proporciona una forma de obtener buenos resultados de consultas naturales, que no tienen operadores booleanos como strpos(), preg_match(), strstr() o stristr().

NOTA BENE

Opcionalmente eliminando la redundancia antes de buscar las palabras

  • por lo tanto, se reduce el tamaño del índice y se reduce el requisito de almacenamiento

  • menos E / S de disco

  • una indexación más rápida y, en consecuencia, una búsqueda más rápida.

1. Normalización

  • Convierta todo el texto a minúsculas

2. Eliminación de palabras prohibidas

  • Elimina las palabras del texto que no tienen ningún significado real (como 'y', 'o', 'el', 'para', etc.)

3. Sustitución del diccionario

  • Reemplace palabras con otras que tengan un significado idéntico o similar. (Por ejemplo: reemplazar instancias de 'hambriento' y 'hambriento' con 'hambre')

  • Se pueden realizar otras medidas algorítmicas (bola de nieve) para reducir aún más las palabras a su significado esencial.

  • El reemplazo de nombres de colores con sus equivalentes hexadecimales

  • La reducción de los valores numéricos al reducir la precisión son otras formas de normalizar el texto.

RECURSOS 


35