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')
?
Puede 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 la variable booleana false
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')
.
Podría usar expresiones regulares, es mejor para la coincidencia de palabras en comparación con strpos
como lo mencionaron otros usuarios, también devolverá verdadero para cadenas como tarifas, cuidado, mirada, etc. Esto puede evitarse simplemente en expresiones regulares utilizando los límites de Word.
Un partido simple para son podría ser algo como esto:
$a = 'How are you?';
if (preg_match('/\bare\b/', $a)) {
echo 'true';
}
En el lado del rendimiento, strpos
es aproximadamente tres veces más rápido y ten en mente que cuando hice un millón de comparaciones a la vez, tomó preg_match
1.5 segundos para terminar y para strpos
tomó 0.5 segundos.
Edición: 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';
}
La i
al final de la expresión regular cambia la expresión regular para que no distinga mayúsculas de minúsculas, si no desea eso, puede omitirla.
Ahora, esto puede ser bastante problemático en algunos casos, ya que la cadena $ search no está saneada de ninguna manera, es decir, podría no pasar la comprobación en algunos casos como si $search
sea una entrada del usuario, pueden agregar alguna cadena que pueda 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 la sensibilidad de mayúsculas seleccionable), podría 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.
}
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;
}
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 un Palabra en particular, y no una subcadena .
¿Cual es la diferencia? Las subcadenas pueden aparecer en otras palabras:
Una forma de mitigar esto sería usar una expresión regular junto con Límites de palabra (\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 Edge propios. Los límites de las palabras coinciden con los caracteres que no son de Word (\W
), que serán cualquier cosa que no sea a-z
, A-Z
, 0-9
o _
. Eso significa que los dígitos y los guiones bajos se contarán como caracteres de Word y los escenarios como este fallarán:
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, de todos modos, lo que no siempre es cierto).
Para determinar si una cadena contiene otra cadena, puede usar PHP function 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, regresará a la posición 0, si hace una comparación de ==
que no funcionará, tendrá que hacer un ===
Un signo ==
es una comparación y comprueba 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 AND
tienen el mismo tipo, es decir, ambas son cadenas o ambas son números enteros.
<?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.";
}
?>
Peer a SamGoody y Lego Stormtroopr comenta.
Si está buscando un PHP algoritmo para clasificar los resultados de la búsqueda en función de la 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()
PHP método basado en 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 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 consultas naturales, que no tienen operadores booleanos como strpos()
, preg_match()
, strstr()
o stristr()
.
NOTA BENE
Opcionalmente, eliminar 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
2. Eliminación de palabras clave
3. Sustitución de 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 mediciones algorítmicas adicionales (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
Haga uso de mayúsculas y minúsculas usando stripos()
:
if (stripos($string,$stringToSearch) !== false) {
echo 'true';
}
Si desea evitar el problema "falsey" y "truthy", puede utilizar substr_count:
if (substr_count($a, 'are') > 0) {
echo "at least one 'are' is present!";
}
Es un poco más lento que los strpos pero evita los problemas de comparación.
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 distinga mayúsculas y minúsculas, use la función stristr () .
Estoy un poco impresionado de que ninguna de las respuestas aquí que usaron strpos
, strstr
y funciones similares hayan sido mencionadas Multibyte String Functions todavía (2015-05-08).
Básicamente, si tiene 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 prefiera las funciones con mb_
. Por lo tanto, la respuesta aceptada usaría mb_strpos
o mb_stripos
(para coincidencias que no distinguen mayúsculas y minúsculas) en su lugar:
if (mb_strpos($a,'are') !== false) {
echo 'true';
}
Si no puede garantizar que todos sus datos son 100% en UTF-8 , es posible que desee utilizar las funciones mb_
).
Un buen artículo para comprender por qué es The Absolute Minimum Todo desarrollador de software absolutamente, positivamente debe saber acerca de Unicode y conjuntos de caracteres (¡sin excusas!)Por Joel Spolsky.
if (preg_match('/(are)/', $a)) {
echo 'true';
}
La siguiente función también funciona y no depende de ninguna otra función; utiliza solo PHP manipulación de cadenas. 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
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);
}
strpos
encuentra la posición de la primera aparición de una subcadena que distingue entre mayúsculas y minúsculas en una cadena.stripos
encuentra la posición de la primera aparición de una subcadena que no distingue mayúsculas y minúsculas en una cadena.myFunction($haystack, $needle) === FALSE ? FALSE : TRUE
asegura que myFunction
siempre devuelve un booleano y corrige un comportamiento inesperado cuando el índice de la subcadena es 0.$caseSensitive ? A : B
selecciona strpos
o stripos
para hacer el trabajo, dependiendo del valor de $caseSensitive
.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)
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 ";
}
Tuve algunos problemas con esto, y finalmente elegí crear mi propia solución. Sin usar expresión regular motor:
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 un 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 su función le diga que solo $a
contiene $c
.
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 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';
}
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
}
La versión de mano corta.
$result = false!==strpos($a, 'are');
Debe usar el formato de mayúsculas y minúsculas, por lo tanto, si el valor ingresado está en small
o caps
no 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";
}
?>
Aquí, stripos encuentra la aguja en heystack sin considerando el caso (small/caps).
Muchas de las respuestas que usan substr_count
comprueban si el resultado es >0
. Pero como la declaración if
considera cero el igual que falso , puede evitar esa comprobación y escribir directamente:
if (substr_count($a, 'are')) {
Para verificar si no presente, agregue el operador !
:
if (!substr_count($a, 'are')) {
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';
}
}
?>
No use preg_match()
si solo quiere comprobar si una cadena está contenida en otra. Utilice strpos()
o strstr()
en su 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';
}
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.
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';
La función strpos funciona bien, pero si quiere hacer case-insensitive
buscando una palabra en un párrafo, puede usar la función stripos
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 que no distingue entre 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.
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 de especificar los separadores es utilizar 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 Word es en el sentido del motor de expresión regular de PCRE, donde las palabras son subcadenas que consisten solo en caracteres de Word, y están separadas por caracteres que no son de Word.
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 (..)
Una cadena se puede verificar con la siguiente función:
function either_String_existor_not($str, $character) {
if (strpos($str, $character) !== false) {
return true;
}
return false;
}
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 puede utilizar la función strpos()
.
Utilizar:
$text = 'This is a test';
echo substr_count($text, 'is'); // 2
// So if you want to check if is exists in the text just put
// in a condition like this:
if (substr_count($text, 'is') > 0) {
echo "is exists";
}
Una opción más simple:
return ( ! empty($a) && strpos($a, 'are'))? true : false;
Creo que una buena idea es usar mb_stpos
:
$haystack = 'How are you?';
$needle = 'are';
if (mb_strpos($haystack, $needle) !== false) {
echo 'true';
}
Debido a que esta solución es sensible a mayúsculas y segura para todos los caracteres Unicode .
Pero también puedes hacerlo así ( la respuesta de sauch aún no era ):
if (count(explode($needle, $haystack)) > 1) {
echo 'true';
}
Esta solución también es sensible a mayúsculas y segura para los caracteres Unicode .
Además, usted no usa la negación en la expresión , lo que aumenta la legibilidad del código .
Aquí hay otra solución usando la función :
function isContainsStr($haystack, $needle) {
return count(explode($needle, $haystack)) > 1;
}
if (isContainsStr($haystack, $needle)) {
echo 'true';
}
Utilizar:
$a = 'How are you?';
if (mb_strpos($a, 'are')) {
echo 'true';
}
Realiza una operación de strpos () segura de múltiples bytes.
También puede usar las funciones incorporadas strchr()
y strrchr()
y las extensiones para cadenas de varios bytes mb_strchr()
y mb_strrchr()
. Estas funciones devuelven partes de cadenas y FALSE
si no se encuentra nada.
strchr()
- Encuentra la primera aparición de una cadena (es un alias de strstr()
).strrchr()
- Encuentra la última aparición de un carácter en una cadena.