![](/img/trans.png)
[英]How do I replace all uppercase letters with a dash and lowercase with regex?
[英]Invert case of all letters in a string (uppercase to lowercase and lowercase to uppercase)
如何交换/切换字符串中字符的大小写,例如:
$str = "Hello, My Name is Tom";
运行代码后,我得到如下结果:
$newstr = "hELLO, mY nAME Is tOM";
这甚至可能吗?
如果您的字符串仅为 ASCII,则可以使用 XOR:
$str = "Hello, My Name is Tom";
print strtolower($str) ^ strtoupper($str) ^ $str;
输出:
hELLO, mY nAME IS tOM
好的,我知道您已经有了答案,但是有点晦涩的 strtr() 函数迫切需要用于此目的;)
$str = "Hello, My Name is Tom";
echo strtr($str,
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ');
在功能上与马克的答案非常相似。
preg_replace_callback(
'/[a-z]/i',
function($matches) {
return $matches[0] ^ ' ';
},
$str
)
@xtempore 的解释:
'a' ^ ' '
返回A
。 之所以有效A
是因为A
是 0x41,a
是 0x61(对于所有 AZ 也是如此),并且因为空格是 0x20。 通过异或运算,您正在翻转那一点。 简单来说,您是在大写字母上加上 32 使它们变成小写,并从小写字母中减去 32 使它们变成大写。
最快的方法是使用位掩码。 没有笨重的字符串函数或正则表达式。 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);
我们取$string
的第 N 个字符并执行 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
因此,您使用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)
我们可以反转它:
0110 0001 // 97 (A)
0010 0000 // Bitmask of 32
---------
0100 0001 // 65 (a)
不需要str_replace
或preg_replace
,我们只需交换位以从字符的 ASCII 值中添加或减去 32 并交换大小写。 第 6 位(右起第 6 位)确定字符是大写还是小写。 如果是 0,则为小写,如果为大写,则为 1。 将位从 0 更改为 1 广告 32,获得大写chr()
值,从 1 更改为 0 减去 32,将大写字母变为小写。
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
您需要遍历字符串测试每个字符的大小写,根据需要调用strtolower()
或strtoupper()
,将修改后的字符添加到新字符串。
我知道这个问题很老 - 但这是我的多字节实现的两种风格。
多功能版本:(在这里找到 mb_str_split 函数):
function mb_str_split( $string ) {
# Split at all position not after the start: ^
# and not before the end: $
return preg_split('/(?<!^)(?!$)/u', $string );
}
function mb_is_upper($char) {
return mb_strtolower($char, "UTF-8") != $char;
}
function mb_flip_case($string) {
$characters = mb_str_split($string);
foreach($characters as $key => $character) {
if(mb_is_upper($character))
$character = mb_strtolower($character, 'UTF-8');
else
$character = mb_strtoupper($character, 'UTF-8');
$characters[$key] = $character;
}
return implode('',$characters);
}
单功能版本:
function mb_flip_case($string) {
$characters = preg_split('/(?<!^)(?!$)/u', $string );
foreach($characters as $key => $character) {
if(mb_strtolower($character, "UTF-8") != $character)
$character = mb_strtolower($character, 'UTF-8');
else
$character = mb_strtoupper($character, 'UTF-8');
$characters[$key] = $character;
}
return implode('',$characters);
}
以下脚本支持 UTF-8 字符,如“ą”等。
PHP 7.1+
$before = 'aaAAąAŚĆżź'; $after = preg_replace_callback('/./u', function (array $char) { [$char] = $char; return $char === ($charLower = mb_strtolower($char)) ? mb_strtoupper($char) : $charLower; }, $before);
PHP 7.4+
$before = 'aaAAąAŚĆżź'; $after = implode(array_map(function (string $char) { return $char === ($charLower = mb_strtolower($char)) ? mb_strtoupper($char) : $charLower; }, mb_str_split($before)));
$before
: aaAAąAŚĆżź
$after
: AAaaĄaśćŻŹ
我想一个解决方案可能是使用这样的东西:
$str = "Hello, My Name is Tom";
$newStr = '';
$length = strlen($str);
for ($i=0 ; $i<$length ; $i++) {
if ($str[$i] >= 'A' && $str[$i] <= 'Z') {
$newStr .= strtolower($str[$i]);
} else if ($str[$i] >= 'a' && $str[$i] <= 'z') {
$newStr .= strtoupper($str[$i]);
} else {
$newStr .= $str[$i];
}
}
echo $newStr;
这让你:
hELLO, mY nAME IS tOM
即你:
问题是这可能不适用于像重音这样的特殊字符:-(
这是一个可能(或可能不)适用于其他一些角色的快速建议:
$str = "Hello, My Name is Tom";
$newStr = '';
$length = strlen($str);
for ($i=0 ; $i<$length ; $i++) {
if (strtoupper($str[$i]) == $str[$i]) {
// Putting to upper case doesn't change the character
// => it's already in upper case => must be put to lower case
$newStr .= strtolower($str[$i]);
} else {
// Putting to upper changes the character
// => it's in lower case => must be transformed to upper case
$newStr .= strtoupper($str[$i]);
}
}
echo $newStr;
现在的一个想法是使用mb_strtolower
和mb_strtoupper
:它可能有助于特殊字符和多字节编码......
如何交换/切换字符串中字符的大小写,例如:
$str = "Hello, My Name is Tom";
运行代码后,我得到如下结果:
$newstr = "hELLO, mY nAME Is tOM";
这有可能吗?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.