Le moyen le plus rapide est avec un masque de bits. Aucune fonction de chaîne maladroite ou regex. PHP est un wrapper C, donc on peut manipuler des bits assez facilement si vous savez que votre fonction logique comme OR, NOT, AND, XOR, NON-ET, etc ..:
function swapCase($string) {
for ($i = 0; $i < strlen($string); $i++) {
$char = ord($string{$i});
if (($char > 64 && $char < 91) || ($char > 96 && $char < 123)) {
$string{$i} = chr($char^32);
}
}
return $string;
}
C'est ce qui le change:
$string{$i} = chr($char^32);
Nous prenons le caractère Nième $string
et effectuer un XOR (^) indiquant l'interpréteur de prendre la valeur entière de $char
et échangeant le sixième bit (32) à partir d'un 1 à 0 ou de 0 à 1.
Tous les caractères ASCII sont à 32 de leurs homologues (ASCII était un conception ingénieuse à cause de cela. Puisque 32 est une puissance de 2 (2^5), il est facile de décaler les bits. Pour obtenir la valeur ASCII d'une lettre, utilisez la fonction intégrée de PHP ord()
:
ord('a') // 65
ord('A') // 97
// 97 - 65 = 32
Vous boucle à travers la chaîne en utilisant strlen()
comme la partie centrale de la boucle for
, et il bouclera sur exactement le nombre de fois comme votre chaîne a des lettres. Si le caractère à la position $i
est une lettre (a-z (65-90) ou A-Z (97-122)), il échangera ce caractère pour la contrepartie majuscule ou minuscule en utilisant un masque de bits.
Voilà comment le bitmask fonctionne:
0100 0001 // 65 (lowercase a)
0010 0000 // 32 (bitmask of 32)
--------- // XOR means: we put a 1 if the bits are different, a 0 if they are same.
0110 0001 // 97 (uppercase A)
Nous pouvons inverser:
0110 0001 // 97 (A)
0010 0000 // Bitmask of 32
---------
0100 0001 // 65 (a)
Pas besoin de str_replace
ou preg_replace
, on échange seulement des bits pour ajouter ou soustraire 32 de la valeur ASCII le personnage et nous échangeons les cas. Le 6ème bit (6ème à partir de la droite) détermine si le caractère est en majuscule ou en minuscule. Si c'est 0, c'est minuscule et 1 si majuscule. Changer le bit d'un 0 à un 1 annonces 32, obtenant la valeur chr()
majuscule, et changeant d'un 1 à un 0 soustrait 32, tournant une majuscule minuscule.
swapCase('userId'); // USERiD
swapCase('USERiD'); // userId
swapCase('rot13'); // ROT13
Nous pouvons aussi avoir une fonction qui intervertit le cas sur un caractère particulier:
// $i = position in string
function swapCaseAtChar($string, $i) {
$char = ord($string{$i});
if (($char > 64 && $char < 91) || ($char > 96 && $char < 123)) {
$string{$i} = chr($char^32);
return $string;
} else {
return $string;
}
}
echo swapCaseAtChar('iiiiiiii', 0); // Iiiiiiii
echo swapCaseAtChar('userid', 4); // userId
// Numbers are no issue
echo swapCaseAtChar('12345qqq', 7); // 12345qqQ
Toute idée comment vérifier le cas d'une chaîne? – tarnfeld
Cela fonctionnera probablement uniquement pour les caractères ASCII. Une alternative à 'strotolower()' pourrait être 'mb_strtolower()'. – Messa
'ctype_lower()' http://php.net/manual/fr/function.ctype-lower.php –