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

2661

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

Charles Yeung
fuente

Respuestas:

6895

Puede usar la strpos()función 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 !== falsees deliberado ( != falseni === truedevolverá el resultado deseado); strpos()devuelve el desplazamiento en el que comienza la secuencia de agujas en la secuencia de pajar o el valor booleano falsesi 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').

codaddict
fuente
261
Muy tarde a la fiesta, pero ten cuidado con esto. Esto también devolverá verdadero para la cadena '¿Te importa?'
DTest
167
@DTest: bueno, sí, por supuesto, devolverá verdadero porque la cadena contiene 'are'. Si está buscando específicamente la palabra ARE, entonces necesitaría hacer más verificaciones como, por ejemplo, verificar si hay un carácter o un espacio antes de la A y después de la E.
jsherk
40
Muy buenos comentarios arriba! ¡Nunca uso! = O ==, después de todo! == y === es la mejor opción (en mi opinión) todos los aspectos considerados (velocidad, precisión, etc.).
Melsi
10
@jsherk ¿Por qué no regexes, entonces? Algo así como "son".
Giulio Muscarello
22
Tiendo a evitar este problema usando siempre strpos($a, 'are') > -1para probar si es verdadero. Desde una perspectiva de depuración, encuentro que mi cerebro desperdicia menos ciclos de reloj para determinar si la línea está escrita correctamente cuando no tengo que contar signos iguales contiguos.
equazcion
608

Puede usar expresiones regulares, es mejor para la coincidencia de palabras en comparación con strposlo mencionado por otros usuarios, también devolverá verdadero para cadenas como tarifa, cuidado, mirada fija, etc. Esto simplemente se puede evitar en la expresión regular mediante el uso de límites de palabras.

Una coincidencia simple para se podría ver más o menos así:

$a = 'How are you?';

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

Por el lado del rendimiento, strposes aproximadamente tres veces más rápido y tenga en cuenta que cuando hice un millón de comparaciones a la vez, tardé preg_match1.5 segundos en terminar y para strpos0.5 segundos.

Editar: para buscar cualquier parte de la cadena, no solo palabra por palabra, recomendaría usar una expresión regular como

$a = 'How are you?';
$search = 'are y';
if(preg_match("/{$search}/i", $a)) {
    echo 'true';
}

El ifinal de la expresión regular cambia la expresión regular para que no distinga entre mayúsculas y minúsculas, si no lo desea, puede omitirlo.

Ahora, esto puede ser bastante problemático en algunos casos ya que la cadena de búsqueda $ no está desinfectada de ninguna manera, es decir, puede que no pase la verificación en algunos casos, ya que si $searches una entrada del usuario, pueden agregar alguna cadena que podría comportarse como alguna expresión regular diferente ...

Además, aquí hay una gran herramienta para probar y ver explicaciones de varias expresiones regulares Regex101

Para combinar ambos conjuntos de funciones en una sola función multipropósito (incluso con mayúsculas y minúsculas seleccionables), puede usar algo como esto:

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.
}
Breezer
fuente
99
@ Alexander.Plutov en segundo lugar me estás dando un -1 y no la pregunta? cmon tarda 2 segundos en google la respuesta google.com/…
Breezer
64
+1 Es una forma horrible de buscar una cadena simple, pero muchos visitantes de SO están buscando cualquier forma de buscar cualquiera de sus propias subcadenas, y es útil que se haya presentado la sugerencia. Incluso el OP podría haberse simplificado demasiado: hágale saber sus alternativas.
SamGoody
72
Técnicamente, la pregunta pregunta cómo encontrar palabras, no una subcadena. Esto realmente me ayudó, ya que puedo usar esto con límites de palabras regex. Las alternativas siempre son útiles.
15
+1 para la respuesta y -1 para el comentario de @ plutov.by porque, strpos es solo una verificación, mientras que regexp puede verificar muchas palabras al mismo tiempo ej: preg_match (/ are | you | not /)
albanx
44
Las expresiones regulares deberían ser el método de último recurso. Su uso en tareas triviales debe ser desalentado. Insisto en esto desde la altura de muchos años de cavar códigos incorrectos.
yentsun
257

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;
}
ejunker
fuente
74
@RobinvanBaalen En realidad, puede mejorar la legibilidad del código. Además, se supone que los votos negativos son para (muy) malas respuestas, no para respuestas "neutrales".
Xaqq
37
Las funciones de @RobinvanBaalen son casi por definición de legibilidad (para comunicar la idea de lo que estás haciendo). Compare cuál es más legible: if ($email->contains("@") && $email->endsWith(".com)) { ...oif (strpos($email, "@") !== false && substr($email, -strlen(".com")) == ".com") { ...
Brandin
3
@RobinvanBaalen, al final, las reglas están destinadas a romperse. De lo contrario, las personas no encontrarían nuevas formas inventivas de hacer las cosas :). Además, tengo que admitir que tengo problemas para comprender todo, como en martinfowler.com. Supongo que lo correcto es probar las cosas usted mismo y descubrir qué enfoques son los más convenientes.
James P.
55
Otra opinión: tener una función de utilidad que pueda ajustar fácilmente puede ayudar a la depuración. También reduce el clamor por buenos optimizadores que eliminen tales gastos generales en los servicios de producción. Entonces todas las opiniones tienen puntos válidos. ;)
Tino
18
Por supuesto, esto es útil. Deberías alentar esto. ¿Qué sucede si en PHP 100 hay una forma nueva y más rápida de encontrar ubicaciones de cadenas? ¿Quieres cambiar todos tus lugares donde llamas strpos? ¿O quieres cambiar solo los contenidos dentro de la función?
Cosmin
143

Si bien la mayoría de estas respuestas le dirán si aparece una subcadena en su cadena, eso generalmente no es lo que desea 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 comienzo del "área"
  • Los "son" al final de "liebre"
  • Los "están" en medio de las "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 mencionados anteriormente, pero tiene algunos casos extremos propios. Límites de las palabras coinciden en caracteres que no son de texto ( \W), que van a ser cualquier cosa que no es a-z, A-Z, 0-9, o _. Eso significa que los dígitos y los guiones bajos se contarán como caracteres de palabras y escenarios como este fallarán:

  • Los "son" en "¿Qué estás pensando?"
  • El "are" en "lol u dunno wut esos 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 bastante grande de gusanos (y supone un uso adecuado de la sintaxis, lo cual no siempre es un hecho).

FtDRbwLXw6
fuente
24
Esta debería ser la respuesta canónica. Debido a que estamos buscando palabras y no subcadenas , la expresión regular es apropiada. También agregaré que \bcoincide con dos cosas que \Wno lo hacen, lo que lo hace ideal para encontrar palabras en una cadena: coincide con el comienzo de la cadena ( ^) y el final de la cadena ( $)
code_monk
esta debería ser la respuesta correcta ... el resto de las respuestas encontrarán "están" en una cadena como "¿te importa?". Como lo mencionó @Dtest
Robert Sinclair
@RobertSinclair ¿Eso es tan malo? Si me preguntaras si la cadena "¿te importa?" Contiene la palabra "son", diría "sí". La palabra "son" es claramente una subcadena de esa cadena. Esa es una pregunta separada de "" "Es" son "una de las palabras en la cadena" ¿te importa? "" ".
Paul
@Paulpro Eventhough OP no especificó que $ a es una frase, estoy bastante seguro de que estaba implícito. Entonces su pregunta era cómo detectar la Palabra dentro de la Frase. No, si una palabra contiene una palabra dentro de ella, lo que supongo que sería irrelevante la mayoría de las veces.
Robert Sinclair
@Jimbo funciona, solo te estás perdiendo el `\` 3v4l.org/ZRpYi
MetalWeirdo
125

Para determinar si una cadena contiene otra cadena, puede usar la función 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 comienzo del pajar, volverá a la posición 0, si realiza una ==comparación que no funcionará, deberá hacer un===

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, ambas son cadenas o ambas son enteros.

Jose Vega
fuente
67

Mirastrpos() :

<?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.";
    }
?>
Haim Evgi
fuente
62

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

glutorange
fuente
99
Una nota en la página php.net/manual/en/function.strstr.php : Nota: Si solo desea determinar si una aguja en particular se produce dentro del pajar, utilice en su lugar la función strpos () más rápida y menos intensiva en memoria.
Jo Smo
@tastro ¿Hay algún punto de referencia acreditado sobre esto?
Wayne Whitty
Esto podría ser más lento, pero en mi humilde opinión strstr($a, 'are')es mucho más elegante que lo feo strpos($a, 'are') !== false. PHP realmente necesita una str_contains()función.
Paul Spiegel
Me
sorprende
45

Utilice la coincidencia entre mayúsculas y minúsculas utilizando stripos():

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

Mira los comentarios de SamGoody y Lego Stormtroopr.

Si está buscando un algoritmo PHP para clasificar los resultados de búsqueda en función de la proximidad / relevancia de varias palabras, aquí viene 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 booleana como strpos(), preg_match(), strstr()ostristr()

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

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

Suena difícil pero es sorprendentemente fácil.

Si queremos buscar varias palabras en una cadena, el problema central 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 cuán 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
)

Hay un montón de mejoras a realizar, pero el modelo proporciona una manera de conseguir buenos resultados de las consultas naturales, que no tienen los operadores booleanos tales 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 resultando en un menor requerimiento de almacenamiento

  • menos E / S de disco

  • indexación más rápida y consecuentemente una búsqueda más rápida.

1. Normalización

  • Convierta todo el texto a minúsculas

2. Eliminación de palabras vacías

  • Elimine 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 con sus equivalentes hexadecimales

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

RECURSOS

RafaSashi
fuente
40

Si desea evitar el problema "falsey" y "verdadero", 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.

Alan Piralla
fuente
Vuelve falsepara "¿estás seguro?" ya que la posición para strposes0
Hafenkranich
30

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 distingue entre mayúsculas y minúsculas, use la función stristr () .

YashG99
fuente
1
strstr () devuelve FALSE si no se encontró la aguja. Entonces un strlen no es necesario.
Ayesh K
29
if (preg_match('/(are)/', $a)) {
   echo 'true';
}
joan16v
fuente
3
Recibo la siguiente advertencia:WARNING preg_match(): Delimiter must not be alphanumeric or backslash
Pathros
27

Estoy un poco impresionado de que ninguna de las respuestas que usé aquí strpos, strstry funciones similares mencionen las funciones de cadena multibyte 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_strposo mb_stripos(para la coincidencia entre mayúsculas y minúsculas) en su lugar:

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

Si no puede garantizar que todos sus datos estén al 100% en UTF-8 , puede utilizar las mb_funciones.

Un buen artículo para entender por qué es El mínimo absoluto que todo desarrollador de software debe saber absolutamente, positivamente sobre Unicode y los conjuntos de caracteres (¡Sin excusas!) Por Joel Spolsky .

Brazo
fuente
25

En PHP, la mejor manera de verificar si una cadena contiene una determinada subcadena es usar una función auxiliar simple como esta:

function contains($haystack, $needle, $caseSensitive = false) {
    return $caseSensitive ?
            (strpos($haystack, $needle) === FALSE ? FALSE : TRUE):
            (stripos($haystack, $needle) === FALSE ? FALSE : TRUE);
}

Explicación:

  • strpos encuentra la posición de la primera aparición de una subcadena sensible a mayúsculas y minúsculas en una cadena.
  • stripos encuentra la posición de la primera aparición de una subcadena insensible a mayúsculas y minúsculas en una cadena.
  • myFunction($haystack, $needle) === FALSE ? FALSE : TRUEgarantiza que myFunctionsiempre devuelve un valor booleano y corrige un comportamiento inesperado cuando el índice de la subcadena es 0.
  • $caseSensitive ? A : Bselecciona ya sea strposo stripospara hacer el trabajo, dependiendo del valor de $caseSensitive.

Salida:

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)
John Slegers
fuente
22

La siguiente función también funciona y no depende de ninguna otra función; usa solo manipulación de cadenas PHP nativas. Personalmente, no recomiendo esto, 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 
Jason OOO
fuente
13
¿Podría decirme por qué en el mundo usaría una función como esta, cuando strpos es una solución perfectamente viable? ...
sg3s
3
@ sg3s: tienes toda la razón, sin embargo, los strpos también se basan en algo así, además, no lo publiqué como representante solo por compartir un poco de conocimiento
Jason OOO
la última var_dump es falsa
Sunny
1
@Sunny: era un error tipográfico: var_dump (is_str_contain ("mystringss", "strings")); // cierto
Jason OOO
22

Puedes usar la strstrfunción:

$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 ";
}
Arshid KV
fuente
2
Se bloquea si busca la primera palabra.
T30
20

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

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 su ejemplo:

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

Con los ejemplos anteriores, ambos $ay $bcontiene $c, pero es posible que desee que su función le diga que solo $acontiene $c.

Decebal
fuente
1
probablemente quisiste decir: $found = falseal principio
slownage
1
Es posible que su función no funcione si la palabra está vinculada con una coma, un signo de interrogación o un punto. por ejemplo, "lo que ves es lo que obtienes". y quieres determinar si "get" está en la oración. Observe la parada completa al lado de "get". En este caso, su función devuelve falso. se recomienda usar expresión regular o substr (creo que usa expresión regular de todos modos) para buscar / reemplazar cadenas.
lightbringer
@lightbringer no podría estar más equivocado con su recomendación, ¿qué significa para usted "se recomienda"? No hay una persona suprema que recomiende o apruebe. Se trata del uso del motor de expresión regular en php que es un agujero negro en el lenguaje en sí, es posible que desee intentar poner una coincidencia de expresiones regulares en un bucle y comparar los resultados.
Deccebal
Esta respuesta está mal demostrada y falla con muchos escenarios extendidos. No veo ningún beneficio en entretener esta técnica. Aquí está la función personalizada refinada y la llamada iterada: 3v4l.org/E9dfD No tengo interés en editar este wiki porque considero que es un desperdicio de tiempo de los investigadores.
mickmackusa
18

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

<?php
    $a = 'How are you?';
    if (strstr($a,'are'))  // Case sensitive
        echo 'true';
    if (stristr($a,'are'))  // Case insensitive
        echo 'true';
?>
Sadikhasan
fuente
Esto es al revés. El ien stristrsignifica insensible.
Adam Merrifield
18

Muchas respuestas que usan substr_countcheques si el resultado es >0. Pero como la ifdeclaración considera cero igual a falso , puede evitar ese cheque y escribir directamente:

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

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

if (!substr_count($a, 'are')) {
T30
fuente
Bueno ... parcialmente cierto, en php 0 == falso es verdadero, pero 0 === falso es falso
Andrejs Gubars
17

Se puede hacer de tres maneras diferentes:

 $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
 }
Shashank Singh
fuente
bueno, pero preg_match es arriesgado, ya que puede devolver falso o 0. Deberías estar probando === 1 en el n. ° 3
Cambiaformas el
14

La versión abreviada

$result = false!==strpos($a, 'are');
Somwang Souksavatd
fuente
55
Si bien este fragmento de código puede resolver la pregunta, incluir una explicación realmente ayuda a mejorar la calidad de su publicación. Recuerde que está respondiendo la pregunta para los lectores en el futuro, y que esas personas podrían no conocer los motivos de su sugerencia de código.
Bono
14

Para encontrar una 'palabra', en lugar de la aparición de una serie de letras que de hecho podrían ser 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';
}
DJC
fuente
55
fallará si $stringesAre are, are?
Sunny
13

Debe usar el formato de mayúsculas y minúsculas, por lo que si el valor ingresado está en smallo capsno importará.

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

Aquí stripos encuentra la aguja en el heystack sin considerar el caso (pequeño / tapas).

PHPCode Muestra con salida

Pratik
fuente
13

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';
        }
    }
?>
Mathias Stavrou
fuente
12

No lo use preg_match()si solo desea verificar si una cadena está contenida en otra cadena. Use strpos()o en su strstr()lugar ya que serán más rápidos. ( http://in2.php.net/preg_match )

if (strpos($text, 'string_name') !== false){
   echo 'get the string';
}
Vinod Joshi
fuente
12

Si desea verificar si la cadena contiene varias palabras específicas, puede hacer:

$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.

Julien
fuente
10

La función strpos funciona bien, pero si desea case-insensitiveverificar una palabra en un párrafo, puede utilizar la striposfunción de PHP.

Por ejemplo,

$result = stripos("I love PHP, I love PHP too!", "php");
if ($result === false) {
    // Word does not exist
}
else {
    // Word exists
}

Encuentre la posición de la primera aparición de una subcadena insensible a mayúsculas y minúsculas en una cadena.

Si la palabra no existe en la cadena, devolverá falso, de lo contrario devolverá la posición de la palabra.

Akshay Khale
fuente
9

Debe usar operadores idénticos / no idénticos porque strpos puede devolver 0 como su 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';
Cambiaformas
fuente
8

¿Comprobar 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, el motor de expresión regular PCRE, donde las palabras son subcadenas que consisten solo en caracteres de palabras, 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 puede ser 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 realiza una coincidencia específica de la localidad (..)

mvw
fuente
7

Otra solución para una cadena específica:

$subject = 'How are you?';
$pattern = '/are/';
preg_match($pattern, $subject, $match);
if ($match[0] == 'are') {
    echo true;
}

También puedes usar la strpos()función.

devpro
fuente