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

Resuelto asked hace 54 años • 36 respuestas

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

 avatar Jan 01 '70 08:01
Aceptado

Ahora con PHP 8 puedes hacer esto usando str_contains :

if (str_contains('How are you', 'are')) { 
    echo 'true';
}

Tenga en cuenta : la str_containsfunción siempre devolverá verdadero si $needle (la subcadena a buscar en su cadena) está vacía.

$haystack = 'Hello';
$needle   = '';

if (str_contains($haystack, $needle)) {
    echo "This returned true!";
}

Primero debes asegurarte de que $needle (tu subcadena) no esté vacía.

$haystack = 'How are you?';
$needle   = '';

if ($needle !== '' && str_contains($haystack, $needle)) {
    echo "This returned true!";
} else {
    echo "This returned false!";
}

Producción :This returned false!

También vale la pena señalar que la nueva str_containsfunción distingue entre mayúsculas y minúsculas.

$haystack = 'How are you?';
$needle   = 'how';

if ($needle !== '' && str_contains($haystack, $needle)) {
    echo "This returned true!";
} else {
    echo "This returned false!";
}

Producción :This returned false!

RFC

Antes de PHP 8

Puede utilizar la strpos()función que se utiliza para encontrar la aparición de una cadena dentro de otra:

$haystack = 'How are you?';
$needle   = 'are';

if (strpos($haystack, $needle) !== false) {
    echo 'true';
}

Tenga en cuenta que el uso de !== falsees deliberado (ni != falsedevolverá === trueel resultado deseado); strpos()Devuelve el desplazamiento en el que comienza la cadena de agujas en la cadena del pajar o el valor booleano falsesi no se encuentra la aguja. Dado que 0 es un desplazamiento válido y 0 es "falso", no podemos usar construcciones más simples como !strpos($a, 'are').

SeniorDeveloper avatar Dec 06 '2010 13:12 SeniorDeveloper

Puede utilizar expresiones regulares, ya que es mejor para la coincidencia de palabras en comparación con strpos, como lo mencionaron otros usuarios. Una strposverificación de aretambién devolverá verdadero para cadenas como: tarifa, atención, mirada, etc. Estas coincidencias no deseadas se pueden evitar simplemente en expresiones regulares usando límites de palabras.

Una coincidencia simple arepodría verse así:

$a = 'How are you?';

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

En cuanto al rendimiento, strposes aproximadamente tres veces más rápido. Cuando hice un millón de comparaciones a la vez, me tomó preg_match1,5 segundos terminar y 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';
}

Al ifinal de la expresión regular, la expresión regular cambia 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 $search no está desinfectada de ninguna manera, quiero decir, es posible que no pase la verificación en algunos casos, ya que si $searchfuera 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 funcionalidades en una única función multipropósito (incluso con distinción entre 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.
}

Una cosa más a tener en cuenta es que \bno funcionará en otros idiomas además del inglés.

La explicación de esto y la solución se obtienen de aquí :

\brepresenta el principio o el final de una palabra (límite de palabra). Esta expresión regular coincidiría con la manzana en una tarta de manzana, pero no coincidiría con la manzana en piña, carritos de manzanas o manzanas horneadas.

¿Qué tal “café”? ¿Cómo podemos extraer la palabra “café” en expresiones regulares? En realidad, \bcafé\b no funcionaría. ¿Por qué? Porque “café” contiene caracteres no ASCII: é. \b no se puede usar simplemente con Unicode como समुद्र, 감사, месяц y 😉.

Cuando desee extraer caracteres Unicode, debe definir directamente caracteres que representen límites de palabras.

La respuesta:(?<=[\s,.:;"']|^)UNICODE_WORD(?=[\s,.:;"']|$)

Entonces, para usar la respuesta en PHP, puedes usar esta función:

function contains($str, array $arr) {
    // Works in Hebrew and any other unicode characters
    // Thanks https://medium.com/@shiba1014/regex-word-boundaries-with-unicode-207794f6e7ed
    // Thanks https://www.phpliveregex.com/
    if (preg_match('/(?<=[\s,.:;"\']|^)' . $word . '(?=[\s,.:;"\']|$)/', $str)) return true;
}

Y si desea buscar una variedad de palabras, puede usar esto:

function arrayContainsWord($str, array $arr)
{
    foreach ($arr as $word) {
        // Works in Hebrew and any other unicode characters
        // Thanks https://medium.com/@shiba1014/regex-word-boundaries-with-unicode-207794f6e7ed
        // Thanks https://www.phpliveregex.com/
        if (preg_match('/(?<=[\s,.:;"\']|^)' . $word . '(?=[\s,.:;"\']|$)/', $str)) return true;
    }
    return false;
}

A partir de PHP 8.0.0 ahora puedes usar str_contains

<?php
    if (str_contains('abc', '')) {
        echo "Checking the existence of the empty string will always"
        return true;
    }
Elron avatar Dec 06 '2010 13:12 Elron