recorrer - validar cadenas en php
Comparación de cadenas insensibles a mayúsculas (6)
Me gustaría comparar dos variables para ver si son iguales, pero quiero que esta comparación no distinga entre mayúsculas y minúsculas.
Por ejemplo, esto sería sensible a mayúsculas y minúsculas:
if($var1 == $var2){
...
}
Pero quiero que esto no distinga entre mayúsculas y minúsculas, ¿cómo podría abordar esto?
Esto es bastante simple; solo necesita llamar a strtolower()
en ambas variables.
Si necesita tratar con conjuntos de caracteres Unicode o internacionales, puede usar mb_strtolower()
.
Tenga en cuenta que otras respuestas sugieren usar strcasecmp()
esa función no maneja caracteres multibyte, por lo que los resultados de cualquier cadena UTF-8 serán falsos.
Por qué no:
if(strtolower($var1) == strtolower($var2)){
}
Si su cadena está en una codificación de un solo byte, es simple:
if(strtolower($var1) === strtolower($var2))
Si su cadena es UTF-8, debe considerar la complejidad de Unicode: en minúsculas y en mayúsculas no son funciones biyectivas, es decir, si tiene un carácter en minúscula, transmítalo a mayúsculas y transforme volver a minúsculas, puede que no termines con el mismo punto de código (y lo mismo ocurre si comienzas con un carácter en mayúscula).
P.ej
- "İ" (
Latin Capital Letter I with Dot Above, U+0130
mayúsculaLatin Capital Letter I with Dot Above, U+0130
) es un carácter en mayúscula, con "i" (Latin Small Letter I, U+0069
) como su variante minúscula - y mayúscula "i" la variante es "I" (Latin Capital Letter I, U+0049
). - "ı" (
Latin Small Letter Dotless I, U+0131
) es un carácter en minúsculas, con "I" (Latin Capital Letter I, U+0049
mayúsculaLatin Capital Letter I, U+0049
) como su variante en mayúscula - y la variante en minúscula "I" "yo" (Latin Small Letter I, U+0069
)
Entonces mb_strtolower(''ı'') === mb_strtolower(''i'')
devuelve falso, aunque tengan el mismo carácter en mayúscula. Si realmente desea una función de comparación de cadenas insensible a mayúsculas y minúsculas, debe compararla con mayúsculas y minúsculas:
if(mb_strtolower($string1) === mb_strtolower($string2)
|| mb_strtoupper($string1) === mb_strtoupper($string2))
He ejecutado una consulta en la base de datos Unicode desde https://codepoints.net ( https://dumps.codepoints.net ) y encontré 180 puntos de código para los que encontré un personaje diferente al tomar una letra minúscula. minúsculas, y 8 puntos de código para los que encontré un personaje diferente al tomar mayúsculas en minúsculas de mayúsculas y minúsculas
Pero empeora : el mismo grupo de grafemas visto por el usuario puede tener múltiples formas de codificarlo: "ä" puede representarse como Latin Small Letter a with Diaeresis (U+00E4)
o como Latin Small Letter A (U+0061)
y Combining Diaeresis (U+0308)
- y si los compara a nivel de byte, ¡esto no será verdadero!
Pero hay una solución para esto en Unicode: ¡ Normalization ! Hay cuatro formas diferentes: NFC, NFD, NFKC, NFKD. Para la comparación de cadenas, NFC y NFD son equivalentes y NFKC y NFKD son equivalentes. Tomaría NFKC porque es más corto que NFKD, y "ff" (Ligadura Latin Small Ligature ff, U+FB00
) se transformará en dos "f" normales (pero 2⁵ también se expandirán a 25 ...).
La función resultante se convierte en:
function mb_is_string_equal_ci($string1, $string2) {
$string1_normalized = Normalizer::normalize($string1, Normalizer::FORM_KC);
$string2_normalized = Normalizer::normalize($string2, Normalizer::FORM_KC);
return mb_strtolower($string1_normalized) === mb_strtolower($string2_normalized)
|| mb_strtoupper($string1_normalized) === mb_strtoupper($string2_normalized);
}
Tenga en cuenta:
- necesitas el paquete intl para el Normalizer
- debe optimizar esta función comprobando primero si son iguales ^^
- es posible que desee utilizar NFC en lugar de NFKC, porque NFKC elimina demasiadas distinciones de formato para su gusto
- tienes que decidir por ti mismo, si realmente necesitas toda esta complejidad o si prefieres una variante más simple de esta función
Use strcasecmp() .
strcasecmp()
devuelve 0 si las cadenas son las mismas (además de las variaciones de casos) para que pueda usar:
if (strcasecmp($var1, $var2) == 0) {
}
if(strtolower($var1) == strtolower($var2)){
}