Loading ...
Sorry, an error occurred while loading the content.

RE: [PBML] TR(anslate) using variables?

Expand Messages
  • Smith, Sheldon
    Ah. The key I was missing was the backslash ahead of lval variable name! Thank you Mr. Johnson! ... Oops. Right on both counts.
    Message 1 of 4 , Sep 28, 2000
    • 0 Attachment
      Ah. The key I was missing was the backslash ahead of lval variable name!

      Thank you Mr. Johnson!

      > -----Original Message-----
      > From: Andrew Johnson [mailto:andrew-johnson@...]
      > Sent: Wednesday, September 27, 2000 6:37 PM
      > To: perl-beginner@egroups.com
      > Subject: Re: [PBML] TR(anslate) using variables?
      >
      >
      > ! Is there a way to get the "tr" function to use a *variable*
      > instead of a
      > ! character string?
      > !
      > ! $myKey = 'abcdefghij';
      > ! $myString = '952 555 1212';
      > !
      > ! $myString = tr/0-9/$myKey/;
      > !
      > ! I would like $myString to become "jeb eee abab".
      >
      > Hmm surely you mean =~ instead of = in that last line of code?
      > And are you sure you don't want: "jfc fff bcbc" ??

      Oops. Right on both counts.

      > You may use string eval() to dynamically interpolate variables in a
      > tr/// operator:
      >
      > $myKey = 'abcdefghij';
      > $myString = '952 555 1212';
      >
      > eval "\$myString =~ tr/0-9/$myKey/";
      > die $@ if $@; # catch any fatal errors and die
      > print $myString;
      > __END__
      > output:
      > jfc fff bcbc
      >
      > Just be very careful from whence you get $myKey -- if you get it
      > from user input it could contain anything:
      >
      > $myKey = q|abcdefghij/;print qq/I could have run "system
      > 'rm -rf .'"\n|;
      > $myString = '952 555 1212';
      >
      > eval "\$myString =~ tr/0-9/$myKey/";
      > die $@ if $@;
      > print $myString;
      > __END__
      > output:
      > I could have run "system 'rm -rf .'"
      > jfc fff bcbc
      >
      > Alternatively, you could use s///g and map the letters to the
      > indices of an array:
      >
      > my @mapping = qw/a b c d e f g h i j/;
      > my $string = '952 555 1212';
      > $string =~ s/(\d)/$mapping[$1]/g;
      > print $string;
      >
      > Normally, tr/// is faster than s///g for single character
      > substitution, but if your strings are always this short, then the
      > cost of the eval() outweighs this gain -- however if your strings
      > get much longer the eval(tr///) version will overtake the s///g
      > version again (at what point exactly I don't know, you'll have to
      > benchmark it with different sizes if it matters).
      >
      > regards,
      > andrew
    Your message has been successfully submitted and would be delivered to recipients shortly.