Cody Pendant has asked for the wisdom of the Perl Monks concerning the following question:

I was messing about with tr/// today, and I thought that I should be putting character classes into it, the way that you would with s///;

But look at this:

$x = 'Just Another Perl Hacker'; $x =~ tr/[A-Z]/a-z /; print $x;

Prints out "kust bnother qerl iacker". Can someone explain this?
--

($_='jjjuuusssttt annootthhrer pppeeerrrlll haaaccckkeer')=~y/a-z//s;print;

Replies are listed 'Best First'.
Re: kust bnother qerl iacker?
by snowcrash (Friar) on Feb 28, 2002 at 08:25 UTC
    the brackets in the search list are treated as actual characters to replace. so [ is replaced with a, A is replaced with b, and so on...
    snowcrash
Re: kust bnother qerl iacker?
by Anonymous Monk on Feb 28, 2002 at 09:13 UTC
    $x =~ tr/[A-Z]/a-z /; #Wrong, need [] around a-z.

    $x =~ tr/[A-Z]/[a-z]/; # Right, also no space needed after z. you left off the [] around a-z, as to why it shifts all replacements down on letter I don't know.

    pualc.

    Repaired square brackets - 2002-02-28 - dvergin

      Not quite. You do not need brackets around the character sets with tr. If you put brackets around in both cases, then you're just adding two characters (mapped to themselves) in the transliteration list, at best, and (if the left bracket is already in the list, mapped to something other than the left bracket) possibly breaking the transliteration, at worst. You're right about the space not being needed, though in this particular case it doesn't do any harm.