切换字符大小写,php

时间:2010-02-14 00:22:19

标签: php string case

如何在字符串中交换/切换字符的大小写,例如:

$str = "Hello, My Name is Tom";

运行代码后,得到如下结果:

$newstr = "hELLO, mY nAME Is tOM";

这甚至可能吗?

10 个答案:

答案 0 :(得分:58)

如果您的字符串仅为ASCII,则可以使用XOR:

$str = "Hello, My Name is Tom";

print strtolower($str) ^ strtoupper($str) ^ $str;

输出:

hELLO, mY nAME IS tOM

答案 1 :(得分:9)

好的我知道你已经得到了答案,但是有点模糊的strtr()函数却急于用于此;)

$str = "Hello, My Name is Tom";
echo strtr($str, 
           'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',
           'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ');

答案 2 :(得分:4)

功能与Mark的答案非常相似。

preg_replace_callback(
    '/[a-z]/i',
    function($matches) {
        return $matches[0] ^ ' ';
    },
    $str
)

答案 3 :(得分:2)

最快的方法是使用位掩码。没有笨重的字符串函数或正则表达式。 PHP是C的包装器,所以如果你知道你的逻辑函数如OR,NOT,AND,XOR,NAND等,我们可以很容易地操作位。:

regToken

这就改变了它:

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个字符并执行XOR(^),告诉解释器取整数值$string并将第6位(32)从1交换为0或0到1。

所有ASCII字符都与它们的对应物相差32个(因为这是一个巧妙的设计。由于32是2(2 ^ 5)的幂,它很容易移位。要获得ASCII值一封信,使用内置的PHP函数$char

ord()

所以你使用ord('a') // 65 ord('A') // 97 // 97 - 65 = 32 循环遍历字符串作为strlen()循环的中间部分,并且它将完全循环,因为你的字符串有字母。如果位置for处的字符是字母(a-z(65-90)或A-Z(97-122)),它将使用位掩码将该字符替换为大写或小写对应字符。

以下是位掩码的工作原理:

$i

我们可以改变它:

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,我们只需交换位以从字符的ASCII值中添加或减去32,我们就会交换案例。第6位(右起第6位)确定字符是大写还是小写。如果它是0,那么它是小写的,如果是大写的则是1。将位从0更改为1广告32,获取大写preg_replace值,并从1更改为0减去32,将大写字母变为小写。

chr()

我们还可以使用一个函数来交换特定字符的大小写:

swapCase('userId'); // USERiD
swapCase('USERiD'); // userId
swapCase('rot13'); // ROT13

答案 4 :(得分:1)

您需要遍历测试每个字符大小写的字符串,根据需要调用strtolower()strtoupper(),将修改后的字符添加到新字符串中。

答案 5 :(得分:0)

我想解决方案可能是使用这样的东西:

$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


即你:

  • 循环遍历原始字符串的每个字符
  • 如果它在A和Z之间,则将其置于小写
  • 如果它在a和z之间,则将其置于大写
  • 否则,你保持原样

这个问题很可能不适用于像口音这样的特殊字符: - (


这是一个快速提案,可能(或可能不)适用于其他一些角色:

$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_strtolowermb_strtoupper:它可能有助于处理特殊字符和多字节编码......

答案 6 :(得分:0)

我知道这个问题已经过时了 - 但这是我的两种多字节实现方式。

多功能版: (mb_str_split function found here):

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);
}

答案 7 :(得分:0)

以下脚本支持UTF-8字符,如“±”等:

<?php
$str = 'aaAAąAŚĆżź';
$newstr = '';
preg_match_all('#.#u', $str, $match);
foreach ($match[0] as $v)
 $newstr.= (($l=mb_strtolower($v, 'UTF-8')) === $v) ? mb_strtoupper($v, 'UTF-8') : $l;
echo $str, '<br/>', $newstr;

答案 8 :(得分:0)

切换大小写的最简单方法是:

echo "tOGGLE cASE : ".(strtolower($str) ^ strtoupper($str) ^ $str);

答案 9 :(得分:0)

对于多字节/Unicode 安全的解决方案,我可能会建议根据哪个捕获组包含一个字母来改变/切换每个字母的大小写。这样您就不必在将字母与正则表达式匹配后进行多字节检查。

代码:(Demo)

$string = 'aaAAąAŚĆżź';
echo preg_replace_callback(
         '/(\p{Lu})|(\p{Ll})/u',
         function($m) {
             return $m[1]
                 ? mb_strtolower($m[1])
                 : mb_strtoupper($m[2]);
         },
         $string
     );
// AAaaĄaśćŻŹ

有关如何匹配可能是多字节的字母的信息,请参阅 this answer