1

How can I switch the case of every character with PHP like from

I didN't gEt anY dEsseRt

to

i DIDn'T GeT ANy DeSSErT

Is there any PHP code to do this

3 Answers3

4

My initial though was "pff, that's easy". Then I thought again, and it's actually not so simple...

Personally, I'd do it like this:

$upper = range("A","Z");
$lower = range("a","z");
$upper_lower = array_merge($upper,$lower);
$lower_upper = array_merge($lower,$upper);
$replacements = array_combine($upper_lower,$lower_upper);
$output = strtr($input,$replacements);

While Arthur Halma's answer was impressive, it was stolen from here and failed to explain how it works, so here we go!

First, the code:

$output = strtolower($str) ^ strtoupper($str) ^ $str;

Let's start with the ^. It is a very rarely-seen operator: Bitwise XOR. It takes the bits on the left and right side, and applies the XOR algorithm to them. When used on strings, it performs this operation character-by-character.

Here's what the XOR algorithm looks like:

 A | B | A^B
---+---+-----
 0 | 0 |  0
 0 | 1 |  1
 1 | 0 |  1
 1 | 1 |  0

In basic English, it means "if one or other is true, but not both". It's kind of like when you ask "Should I head North or South?" You can't go both ways, so it's an XOR.

Now, let's take a look at the characters in your string. The people who created character sets were very clever, as we shall soon see. If you look at the Character Map, you will find that the letters A to Z take the spaces from 65 to 90, and a to z are 97 to 122. Let's look at them in binary:

A (65) 01000001    Z ( 90) 01011010
a (97) 01100001    z (122) 01111010

You'll notice that, to switch between uppercase and lowercase, all you have to do is toggle that third-highest bit. This is important.

So, on to what the code does! For simplicity, I'll just assume the input string is "a Z", and the desired output will therefore be "A z". Note that space is character 32, or 00100000.

a Z: 01100001 00100000 01011010

First, the code converts the string to uppercase:

A Z: 01000001 00100000 01011010

Then, it converts the string to lowercase:

a z: 01100001 00100000 01111010

Next, it XORs the uppercase and lowercase strings:

A Z: 01000001 00100000 01011010
a z: 01100001 00100000 01111010
^1 : 00100000 00000000 00100000

Now it XORs that against the original string:

^1 : 00100000 00000000 00100000
a Z: 01100001 00100000 01011010
^2 : 01000001 00100000 01111010

Convert that back to characters, and you get... A z. The original string with case reversed.

Genius, right?

Community
  • 1
  • 1
Niet the Dark Absol
  • 320,036
  • 81
  • 464
  • 592
  • Awesome answer, very clear explanation of XOR, a much under used operator these days. – vascowhite Dec 17 '13 at 12:56
  • @vascowhite Thanks :) I should probably go back through my old code and see how often I've written "if (A or B) and not (A and B)", which is basically "if A xor B" but really long-winded XD – Niet the Dark Absol Dec 17 '13 at 13:00
2

split string's character one by one like

$arr = str_split('yourname');

result would be

Array
(
    [0] => y
    [1] => o
    [2] => u
    [3] => r
    [4] => n
    [5] => a
    [6] => m
    [7]=>  e
)

in a loop get elements of array one by one and check if it is in small convert it to Alphabat and vise versa

by strtolower() and strtoupper(); functions.

Engr Saddam Zardari
  • 1,057
  • 1
  • 14
  • 27
0

Convert all the characters of the string into an array and then separately treat them.

    $str = 'I didN\'t gEt anY dEsseRt';
    $chars = str_split($str); //make an array out of the string
    foreach ($chars as $char){
        if (ctype_lower($char)) //is lowercase
           strtoupper ($char); //make uppercase
        if (ctype_upper($char)) //is uppercase
           strtolower ($char); //make lowercase
    }

    $opposite = implode ('', $chars); //convert back into string
Eisa Adil
  • 1,743
  • 11
  • 16