Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.
 
PerlMonks  

Transliteration

by cei (Monk)
on May 03, 2000 at 05:41 UTC ( [id://10022]=perlquestion: print w/replies, xml ) Need Help??

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

Last night I wrote a little program using the Geo::WeatherNOAA module to get the weather forecast for my region and dump it into MySQL. I was a happy little initiate. But I noticed that the strings that NOAA sends back end with a single equal sign.

I use

foreach $key (keys %$forecast) { $fcast .= "$key: $forecast->{$key}<P>\n"; }
to make my forecast one string. I'd like to strip that = off though. I could chomp it but the way my loop is written, my string actually ends with ' =

', so that isn't ideal.

Being a good little monk in training, I thought I'd try transliteration. I know how to change case by saying $email =~ tr/A-Z/a-z/; but how can I transliterate an equal sign into either a space (or delete it entirely)? I tried $fcast =~ tr/=//; and $fcast =~ tr/\=//; with no luck. I'm guessing a 'd' should be in there... maybe $fcast =~ tr/\=//d; but I couldn't seem to get a good result.

Any suggestions, oh wise ones?

Replies are listed 'Best First'.
Re: Transliteration
by ZZamboni (Curate) on May 03, 2000 at 06:02 UTC
    You could use the s operator instead of tr. Something like this:
    $fcast =~ s/=\s*$//g;
    will delete a '=' followed by any amount of whitespace (including newlines) at the end of the string. If each string (this is, each element in %$forecast ends that way, you may want to apply the substitution to each element before concatenating them into $fcast.

    The '=' at the end of each line sounds like some form of MIME encoding to me. If this is the case, and later you encounter that some other things come encoded in funny ways, you may want to look at the existing MIME:: packages on CPAN.

      Which brings us to another interesting question... What is the main difference between tr///? and s///? And I don't mean syntatically speaking!

      Why would someone use one or the other in a specific case? I tend to be more of the sort that always uses s///'s. I have a bad habit of learning one way to do it, and sticking through with what I know works. (other examples would be the use of foreach instead of while, or !($var eq $val) instead of ($var ne $val) and I know the latter is the correct form...)
        The main difference is speed. tr/// doesn't do interpolation or use the regex engine, so it is blazingly fast in comparison. It's very good for transliterating characters (if you've ever studied a dead language that didn't use the Arabic alphabet, you'll understand).

        s/// is more flexible -- it uses the regex engine and allows character classes. It can also perform nearly abitrarily complex interpolation.

        You can get by with just s///, so if you're in doubt, go for it. Just be aware that, used correctly, tr/// will run rings around it.

        I also habitually use s/// where I could use tr///.

        The main difference is with s/// you can use regular expressions, while in tr/// you cannot. Also (from the camel book) "the translation table is built at compile time, neither the SEARCHLIST nor the REPLACEMENTLIST are subject to double quote interpolation." So that means:$str =~ tr/$mylist//d; Will delete all occurances of "$, m, y, l, i, s, t" in $str. Probably not what you want.

        Also since the tr/// cannot use regex's it is usually a lot faster. I did a benchmark to that here.
        damnit, wrong link again... sorry!
Re: Transliteration
by perlmonkey (Hermit) on May 03, 2000 at 06:15 UTC
    Here is a snip from perlop: If the REPLACEMENTLIST is empty, the SEARCHLIST is replicated. So a tr/=// is really a tr/=/=/ and is really only useful for counting the occurance of '=' in your variable. Like this: $cnt = ($fcast =~ tr/=//;) You are right about the d option. That is what worked for me. That will delete what in in the SEARCHLIST, but not in the REPLACEMENT list. Since there is nothing in the REPLACEMENT list everything in the SEARCHLIST ('=' in this case) will be deleted. So I think what you want is:
    $fcast =~ tr/=//d; # or replace with a space $fcast =~ tr/=/ /;
RE: Transliteration
by The Alien (Sexton) on May 03, 2000 at 07:40 UTC
    If you want to kill all equal signs:
    tr/=//d;
    If you only want remove an equal sign at the end of the line(just before any \n or \r):
    s/\=$//;
Re: Transliteration
by btrott (Parson) on May 03, 2000 at 06:16 UTC
    I'm not sure what isn't working for you. You don't need to escape the equal sign, and yes, you need the "d" modifier, unless you're actually replacing the "=" with a space. So, first, to delete it entirely:
    $fcast =~ tr/=//d;
    and now to replace it with a space:
    $fcast =~ tr/=/ /;
      That worked. Wasn't sure on if I needed to be escaping the = or not, and the books weren't helping. Thanks again.
RE: Transliteration
by t0mas (Priest) on May 03, 2000 at 14:09 UTC
    tr replaces character by character. If you want to replace _all_ = with blanks you could use
    tr/=/ /;
    If you want to delete them you use
    tr/=//d;
    If you want to delete last = in a string you could do it with s/// instead like in
    s/=\s*$//;
    that matches a = followed by nothing or whitespace and replaces it with nothing. /t0mas
RE: Transliteration
by Anonymous Monk on May 03, 2000 at 07:22 UTC
    try s/\=$/ /;

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others scrutinizing the Monastery: (4)
As of 2024-04-25 12:11 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found