如何在字符串中交换/切换字符的大小写,例如:
$str = "Hello, My Name is Tom";
Run Code Online (Sandbox Code Playgroud)
运行代码后,我得到一个这样的结果:
$newstr = "hELLO, mY nAME Is tOM";
Run Code Online (Sandbox Code Playgroud)
这甚至可能吗?
Mik*_*ike 62
如果您的字符串仅为ASCII,则可以使用XOR:
$str = "Hello, My Name is Tom";
print strtolower($str) ^ strtoupper($str) ^ $str;
Run Code Online (Sandbox Code Playgroud)
输出:
hELLO, mY nAME IS tOM
Run Code Online (Sandbox Code Playgroud)
小智 9
好的,我知道你已经得到了答案,但有点模糊的strtr()函数迫切需要用于此;)
$str = "Hello, My Name is Tom";
echo strtr($str,
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ');
Run Code Online (Sandbox Code Playgroud)
最快的方法是使用位掩码。没有笨重的字符串函数或正则表达式。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;
}
Run Code Online (Sandbox Code Playgroud)
这就是它的改变:
$string{$i} = chr($char ^ 32);
Run Code Online (Sandbox Code Playgroud)
我们取第 N 个字符$string并执行 XOR (^),告诉解释器取 的整数值$char并将第 6 位 (32) 从 1 交换为 0 或 0 交换为 1。
所有 ASCII 字符与其对应字符相差 32(正因为如此,ASCII 是一个巧妙的设计。由于 32 是 2 的幂 (2^5),因此很容易移位。要获取字母的 ASCII 值,请使用内置的在 PHP 函数中ord():
ord('a') // 65
ord('A') // 97
// 97 - 65 = 32
Run Code Online (Sandbox Code Playgroud)
strlen()因此,您使用循环的中间部分循环遍历字符串for,它将循环的次数与字符串包含字母的次数完全相同。如果该位置的字符$i是字母(az (65-90) 或 AZ (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)
Run Code Online (Sandbox Code Playgroud)
我们可以逆转它:
0110 0001 // 97 (A)
0010 0000 // Bitmask of 32
---------
0100 0001 // 65 (a)
Run Code Online (Sandbox Code Playgroud)
不需要str_replaceor preg_replace,我们只需交换位以从字符的 ASCII 值中添加或减去 32,然后交换大小写。第 6 位(右起第 6 位)确定字符是大写还是小写。如果是 0,则为小写;如果为大写,则为 1。将位从 0 更改为 1 等于 32,得到大写chr()值,从 1 更改为 0 则减去 32,将大写字母变为小写。
swapCase('userId'); // USERiD
swapCase('USERiD'); // userId
swapCase('rot13'); // ROT13
Run Code Online (Sandbox Code Playgroud)
我们还可以有一个函数来交换特定字符的大小写:
// $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
Run Code Online (Sandbox Code Playgroud)
在功能上与马克的答案非常相似。
preg_replace_callback(
'/[a-z]/i',
function($matches) {
return $matches[0] ^ ' ';
},
$str
)
Run Code Online (Sandbox Code Playgroud)
@xtempore 的解释:
'a' ^ ' '返回A。它之所以有效,A是因为0x41 和a0x61(对于所有 AZ 也是如此),并且因为空格是 0x20。通过异或运算,您正在翻转那一点。简单来说,您是在大写字母上加上 32 使它们变成小写,然后从小写字母中减去 32 使它们变成大写。
您需要遍历字符串测试每个字符的大小写,调用strtolower()或strtoupper()根据需要将修改后的字符添加到新字符串中。
| 归档时间: |
|
| 查看次数: |
6059 次 |
| 最近记录: |