php - texto - verificar si existe un caracter en una cadena c#




¿Cómo verifico si una cadena contiene una palabra específica? (20)

Compruebe si la cadena contiene palabras específicas?

Esto significa que la cadena debe resolverse en palabras (vea la nota a continuación).

Una forma de hacer esto y especificar los separadores es usar 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 carrera da

$ 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: Aquí no queremos decir palabra para cada secuencia de símbolos.

Una definición práctica de palabra es en el sentido del motor de expresión regular de PCRE, donde las palabras son subcadenas que consisten solo en caracteres de palabras, y están separadas por caracteres que no son palabras.

Un carácter de "palabra" es cualquier letra o dígito o el carácter de subrayado, es decir, cualquier carácter que pueda formar parte de una "palabra" de Perl. La definición de letras y dígitos está controlada por las tablas de caracteres de PCRE, y puede variar si se lleva a cabo una coincidencia específica del entorno (..)

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 la declaración if ($a contains 'are') ?


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

Debe usar operadores idénticos / no idénticos porque strpos puede devolver 0 como valor de índice. Si le gustan los operadores ternarios, considere usar lo siguiente (parece un poco al revés, lo admito):

echo FALSE === strpos($a,'are') ? 'false': 'true';

El uso de strstr() o stristr() si su búsqueda no debe distinguir entre mayúsculas y minúsculas sería otra opción


Estoy un poco impresionado de que ninguna de las respuestas aquí que utilizaron strpos , strstr y funciones similares mencionara Multibyte String Functions todavía (2015-05-08).

Básicamente, si tiene problemas para encontrar palabras con caracteres específicos de algunos idiomas , como alemán, francés, portugués, español, etc. (por ejemplo: ä , é , ô , ç , º , ñ ), es posible que desee preceder Las funciones con mb_ . Por lo tanto, la respuesta aceptada usaría mb_strpos o mb_stripos (para el emparejamiento insensible a mayúsculas) en su lugar:

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

Si no puede garantizar que todos sus datos mb_ 100% en UTF-8 , puede usar las funciones mb_ .

Un buen artículo para comprender por qué es The Absolute Minimum Todo desarrollador de software Absolutamente, positivamente debe saber sobre Unicode y los conjuntos de caracteres (sin excusas) por Joel Spolsky .


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

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

La siguiente función también funciona y no depende de ninguna otra función; utiliza solo la manipulación de cadenas nativas de PHP. Personalmente, no lo recomiendo, pero puedes ver cómo funciona:

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

Prueba:

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 versión de mano corta.

$result = false!==strpos($a, 'are');

Otra opción es usar la función strstr() . Algo como:

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

Punto a tener en cuenta: la función strstr () distingue entre mayúsculas y minúsculas. Para una búsqueda que no stristr() mayúsculas y minúsculas, use la función stristr() .


Otra opción para encontrar la aparición de una palabra desde una cadena usando strstr() y stristr() es como la siguiente:

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

Para encontrar una 'palabra', en lugar de una serie de letras que de hecho podrían formar parte de otra palabra, lo siguiente sería una buena solución.

$string = 'How are you?';
$array = explode(" ", $string);

if (in_array('are', $array) ) {
    echo 'Found the word';
}

Peer a SamGoody y Lego Stormtroopr comenta.

Si está buscando un algoritmo PHP para clasificar los resultados de búsqueda según la proximidad / relevancia de varias palabras, aquí encontrará una manera rápida y fácil de generar resultados de búsqueda solo con PHP:

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

  1. no puedo buscar múltiples palabras
  2. los resultados no están clasificados

Método PHP basado en Vector Space Model y tf-idf (término frecuencia - frecuencia de documentos inversa):

Suena difícil pero es sorprendentemente fácil.

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

Si pudiéramos ponderar los términos en una cadena en función de qué tan representativos son de la cadena en su conjunto, 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
)

Se pueden realizar muchas mejoras, pero el modelo proporciona una forma de obtener buenos resultados de las 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.

  • reduciendo así el tamaño del índice y dando como resultado menos requisitos de almacenamiento

  • menos E / S de disco

  • Indización más rápida y, por consiguiente, búsqueda más rápida.

1. normalización

  • Convertir todo el texto a minúsculas

2. Eliminación de palabras clave

  • Eliminar palabras del texto que no tengan un significado real (como 'y', 'o', 'el', 'para', etc.)

3. Sustitución del diccionario.

  • Reemplace las palabras con otras que tengan un significado idéntico o similar. (Por ejemplo, reemplace las 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.

  • La sustitución de nombres de colores por sus equivalentes hexadecimales.

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

RECURSOS


Puedes usar la función strpos() que se usa para encontrar la aparición 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 cadena de la aguja en la cadena del pajar, o el false booleano si no se encuentra la aguja. Como 0 es un desplazamiento válido y 0 es "falsey", no podemos usar construcciones más simples como !strpos($a, 'are') .


Puedes usar la función strstr :

$haystack = "I know programming";
$needle   = "know";
$flag = strstr($haystack, $needle);

if ($flag){

    echo "true";
}

Sin usar una función incorporada:

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

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

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

  • Los "son" al principio de "á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 los límites de las 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 mencionados anteriormente, pero sí tiene algunos casos de borde propios. Los límites de palabras coinciden con los caracteres que no son palabras ( \W ), que van a ser cualquier cosa que no sea az , AZ , 0-9 o _ . Eso significa que los dígitos y los guiones bajos se contarán como caracteres de palabras y los escenarios como este fallarán:

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

Si desea algo más preciso que esto, tendrá que comenzar a analizar la sintaxis del idioma inglés, y esa es una lata de gusanos bastante grande (y, de todos modos, supone un uso adecuado de la sintaxis, lo que no siempre es cierto).


Si desea comprobar si la cadena contiene varias palabras específicas, puede hacerlo:

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

Esto es útil para evitar el spam cuando se envían correos electrónicos, por ejemplo.


Tal vez podrías usar algo como esto:

<?php
    findWord('Test all OK');

    function findWord($text) {
        if (strstr($text, 'ok')) {
            echo 'Found a word';
        }
        else
        {
            echo 'Did not find a word';
        }
    }
?>

Tuve algunos problemas con esto, y finalmente elegí crear mi propia solución. Sin usar el motor de expresiones regulares :

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

Puede notar que las soluciones anteriores no son una respuesta para la palabra que se usa como prefijo para otra. Para usar tu ejemplo:

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

Con los ejemplos anteriores, tanto $a como $b contienen $c , pero es posible que desee que su función le diga que solo $a contiene $c .


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

substr_count respuestas que utilizan substr_count comprueban si el resultado es >0 . Pero como la instrucción if considera que cero es lo mismo que falso , puede evitar esa comprobación y escribir directamente:

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

Para comprobar si no está presente, agregue el ! operador:

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




string-matching