Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

Question about tr

by harangzsolt33 (Chaplain)
on Oct 19, 2018 at 05:17 UTC ( [id://1224299]=perlquestion: print w/replies, xml ) Need Help??

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

I am trying to learn how tr really works, and I think I still don't get it. I remember, reading the manual...it said that the character following tr is a separator character, and everything between the separators are characters that will get replaced with a new set of characters defined in the second group. Anyway, I am trying to write a little program that replaces the first 52 bytes of a character map with letters. In other words, in this programming exercise, I am trying to replace binary codes with tr, but tr is not handling these codes very well. For example, it gives an error when I try to convert chr(8) to "I"

Here is my sample code:

#!/usr/bin/perl use strict; use warnings; for (my $i = 0; $i < 52; $i++) { $a = chr($i); $a =~ tr|\0\1\2\3\4\5\6\7\8\t\n\0x0B\r\0x0D\0x0E\0x0F\0x10\0x11\0x12 +\0x13\0x14\0x15\0x16\0x17\0x18\0x19\0x1A\0x1B\0x1C\0x1D\0x1E\0x1F !"# +$%&'()*+,-./0123456789|ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrst +uvwxyz|; print "chr $i -> $a \n"; } exit;

Replies are listed 'Best First'.
Re: Question about tr
by soonix (Canon) on Oct 19, 2018 at 06:54 UTC
    \0, \1, \2, etc. are NOT hexadecimal character codes, but OCTAL. For what you intended, you'd need \10 or \x8, or what nysus wrote. "Accidently", 0 - 7 octal and hexadecimal are the same.

    Update: And, this part \n\0x0B\r\0x0D is wrong - \r is not 0xC but 0xD, so you're skipping chr(12) and have a double chr(13).

      And \0xXX should be \xXX. The former means NUL and three other chars.

Re: Question about tr (updated)
by haukex (Archbishop) on Oct 19, 2018 at 07:46 UTC

    Note that tr/// supports ranges, so this works too: tr|\0-9|A-Za-z|

    (IIRC this might not work on systems that aren't ASCII based; perlebcdic)

    Update: You said "the first 52 bytes of a character map", but \0-9 is the first 58 bytes. So maybe you want to do tr/\0-3/A-Za-z/? Or only the nonprintable characters with tr/\0-\x1F/A-Za-f/?

    Update 2: WebPerl live demo of the following:

    use warnings; use strict; print join(" "," ",map {sprintf "%X.",$_} 0..7), "\n"; for my $l (0..15) { printf ".%X", $l; for my $c ( map { chr( $l|($_<<4) ) } 0..7 ) { #$c =~ tr/\0-9/A-Za-z/; # doesn't work correctly! #$c =~ tr/\0-3/A-Za-z/; # option 1 $c =~ tr/\0-\x1F/A-Za-f/; # option 2 print " $c "; } print "\n"; } __END__ 0. 1. 2. 3. 4. 5. 6. 7. .0 A Q 0 @ P ` p .1 B R ! 1 A Q a q .2 C S " 2 B R b r .3 D T # 3 C S c s .4 E U $ 4 D T d t .5 F V % 5 E U e u .6 G W & 6 F V f v .7 H X ' 7 G W g w .8 I Y ( 8 H X h x .9 J Z ) 9 I Y i y .A K a * : J Z j z .B L b + ; K [ k { .C M c , < L \ l | .D N d - = M ] m } .E O e . > N ^ n ~ .F P f / ? O _ o 
Re: Question about tr
by nysus (Parson) on Oct 19, 2018 at 05:54 UTC

    You need to do this instead:

    $a =~ tr|\x{0000}\x{0001}\x{0002}\x{0003}\x{0004}\x{0005}\x{0006}\x{0007}\x{0008}\x{0009}\x{000a}\x{000b} .... etc.

    See perlrecharclass for more info.

    $PM = "Perl Monk's";
    $MCF = "Most Clueless Friar Abbot Bishop Pontiff Deacon Curate Priest";
    $nysus = $PM . ' ' . $MCF;
    Click here if you love Perl Monks

      Ugh. Now I see so many errors in my original code. It's shameful!

      Thank you for correcting me!

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1224299]
Approved by nysus
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others exploiting the Monastery: (7)
As of 2024-04-19 16:35 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found