Самый быстрый способ - с битовой маской. Нет неуклюжих строковых функций или регулярных выражений. PHP - это оболочка для C, поэтому мы можем легко манипулировать битами, если вы знаете вашу логическую функцию, такую как OR, NOT, AND, XOR, NAND и т. Д.:
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;
}
Вот что это меняет:
$string{$i} = chr($char ^ 32);
Мы берем N-й символ в $string
и выполняем XOR (^), сообщая интерпретатору принять целочисленное значение $char
и меняя шестой бит (32) с 1 на 0 или с 0 на 1.
Все символы ASCII находятся на расстоянии 32 от своих аналогов (ASCII был гениальным дизайном из-за этого. Поскольку 32 - это степень 2 (2 ^ 5), биты легко сдвигать. Чтобы получить значение ASCII для буквы, используйте встроенную функцию PHP ord()
:
ord('a') // 65
ord('A') // 97
// 97 - 65 = 32
Таким образом, вы перебираете строку, используя strlen()
в качестве средней части цикла for
, и она будет повторяться ровно столько раз, сколько в вашей строке букв. Если символ в позиции $i
является буквой (a-z (65-90) или A-Z (97-122)), он заменит этот символ на заглавную или строчную букву, используя битовую маску.
Вот как работает битовая маска:
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)
Мы можем изменить это:
0110 0001 // 97 (A)
0010 0000 // Bitmask of 32
---------
0100 0001 // 65 (a)
Нет необходимости в str_replace
или preg_replace
, мы просто меняем биты, чтобы сложить или вычесть 32 из значения ASCII символа, и мы поменяем регистры. 6-й бит (6-й справа) определяет, является ли символ прописным или строчным. Если это 0, это строчные буквы и 1, если прописные. Изменение бита с 0 на 1 для объявления 32, получение значения chr()
в верхнем регистре и изменение вычитания 32 из 1 в 0, превращение буквы в верхний регистр в нижний регистр.
swapCase('userId'); // USERiD
swapCase('USERiD'); // userId
swapCase('rot13'); // ROT13
У нас также может быть функция, которая меняет регистр на определенный символ:
// $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