Je voudrais comparer deux variables pour voir si elles sont identiques, mais je veux que cette comparaison soit insensible à la casse.
Par exemple, ce serait sensible à la casse:
if($var1 == $var2){
...
}
Mais je veux que ce soit insensible à la casse, comment pourrais-je aborder cela?
C'est assez simple; il vous suffit d'appeler strtolower()
sur les deux variables.
Si vous devez gérer des jeux de caractères Unicode ou internationaux, vous pouvez utiliser mb_strtolower()
.
Veuillez noter que d'autres réponses suggèrent d'utiliser strcasecmp()
- cette fonction ne gère pas les caractères multi-octets, donc les résultats pour toute chaîne UTF-8 sera faux.
strcasecmp()
renvoie 0 si les chaînes sont les mêmes (sauf les variations de casse), vous pouvez donc utiliser:
if (strcasecmp($var1, $var2) == 0) {
}
Si votre chaîne est codée sur un seul octet, c'est simple:
if(strtolower($var1) === strtolower($var2))
Si votre chaîne est UTF-8, vous devez considérer la complexité d'Unicode: en minuscules et en majuscules ne sont pas des fonctions bijectives, c'est-à-dire si vous avez un caractère en minuscules, transformez-le en majuscules et transformez en minuscule, vous ne pouvez pas vous retrouver avec le même point de code (et il en va de même si vous commencez par un caractère majuscule).
Par exemple.
Latin Capital Letter I with Dot Above, U+0130
) Est un caractère majuscule, avec "i" (Latin Small Letter I, U+0069
) Comme variante minuscule - et la variante majuscule "i" est "I" (Latin Capital Letter I, U+0049
).Latin Small Letter Dotless I, U+0131
) est un caractère minuscule, avec "I" (Latin Capital Letter I, U+0049
) comme variante majuscule - et la variante minuscule "I" est "i" (Latin Small Letter I, U+0069
)Donc mb_strtolower('ı') === mb_strtolower('i')
retourne false, même s'ils ont le même caractère majuscule. Si vous voulez vraiment une fonction de comparaison de chaînes insensible à la casse, vous devez comparer avec les majuscules ET la version minuscule:
if(mb_strtolower($string1) === mb_strtolower($string2)
|| mb_strtoupper($string1) === mb_strtoupper($string2))
J'ai exécuté une requête sur la base de données Unicode de https://codepoints.net ( https://dumps.codepoints.net ) et j'ai trouvé 180 codes point pour lequel j'ai trouvé un caractère différent en prenant les minuscules des majuscules des caractères minuscules, et 8 point de code pour lequel j'ai trouvé un caractère différent lors de la prise des majuscules des minuscules des caractères majuscules
Mais ça empire : le même cluster de graphèmes vu par l'utilisateur, peut avoir plusieurs façons de l'encoder: "ä" peut être représenté par la fonction Latin Small Letter a with Diaeresis (U+00E4)
ou comme Latin Small Letter A (U+0061)
et Combining Diaeresis (U+0308)
- et si vous les comparez au niveau d'un octet, cela ne retournera pas vrai!
Mais il existe une solution pour cela en Unicode: Normalisation ! Il existe quatre formes différentes: NFC, NFD, NFKC, NFKD. Pour la comparaison des chaînes, NFC et NFD sont équivalents et NFKC et NFKD sont équivalents. Je prendrais NFKC car il est plus court que NFKD, et "ff" (Latin Small Ligature ff, U+FB00
) Sera être transformé en deux "f" normaux (mais 2⁵ sera également étendu à 25…).
La fonction résultante devient:
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);
}
Notez s'il vous plaît:
if(strtolower($var1) == strtolower($var2)){
}
Utilisez strcasecmp .