in reply to Replace all at once

You need to use the s/// operator to get more flexible replacement. Here is a simple snippet using the technique to get you started:
$string = "We modify foos and bars but not foobars.\n"; my %trans = qw( foo bar bar foo foobar foobar ); # reverse sort is a hack to put strings before # substrings. (ie foobar before foo) my $re_str = join "|", map quotemeta($_), reverse sort keys %trans; $string =~ s/($re_str)/$trans{$1}/g; print $string;
The line where we build up $re_str is a bit tricky if you haven't seen that kind of thing before. The first trick is that you need to read it from right to left. Here are the steps:
  1. Call keys on the translation hash to get a list of strings you want to find.
  2. sort and reverse to put them in reverse sorted order. As the comment says, this is a hack. If your RE had foo appear before foobar, then it would never match "foobar", it would always stop when it found that it could match "foo". (If this comment makes no sense to you, then pick up Mastering Regular Expressions. Or pick up japhy's book when it comes out.)
  3. You then map them through quotemeta. What map does is allows you to transform a list. The transformation that we want in this case is from strings that might contain characters which are meaningful to regular expressions (eg "|") and we want to escape them. Which is what quotemeta does for us.
  4. Then join with a "|". This gives us a string like "foobar|foo|bar" which will now match exactly the keys of our original hash.
And then we do a search and replace. The pattern will match any of our keys. The replacement replaces the hash lookup.

If this answer totally confuses you from start to finish (which I fear it may), then I recommend picking up merlyn's book, Learning Perl. It should (among other things) give you a fairly digestible overview of what regular expressions are, how to read them, and how to produce them. After you have a handle on regular expressions, the above explanation is likely to make more sense.

UPDATE
In response to japhy, I don't mind. :-)

Replies are listed 'Best First'.
Re: Re (tilly) 1: Replace all at once
by japhy (Canon) on Dec 09, 2001 at 00:15 UTC
    Here's an excerpt from chapter 7 (substitution):
    Example 7.4 Sorting text by length for use in a regex.
    $keys = join '|', # 4 map { quotemeta } # 3 sort { length($b) <=> length($a) } # 2 keys %change; # 1
    1. We get the list of keys from the hash – these are the strings...
    2. We sort the keys by their length, so that the longest strings come first...
    3. We run them through the quotemeta() function to make them safe for regexes...
    4. And then we join the regex-safe strings with "|" in between them, for regex alternation.
    Doing a benchmark, I see that the reverse sort LIST method is (as one would imagine) faster than the sort { length($b) <=> length($a) } LIST method (by more than two times). I'll incorporate your code, tilly, if'n you don't mind. :)

    _____________________________________________________
    Jeff[japhy]Pinyan: Perl, regex, and perl hacker.
    s++=END;++y(;-P)}y js++=;shajsj<++y(p-q)}?print:??;

      Why didn't you orcish the sort { length($b) <=> length ($a) }?

      ------
      We are the carpenters and bricklayers of the Information Age.

      Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.

        I was considering doing optimizations, but I didn't want to cloud the meaning. I'm going to do a reverse-sort now, anyways.

        _____________________________________________________
        Jeff[japhy]Pinyan: Perl, regex, and perl hacker.
        s++=END;++y(;-P)}y js++=;shajsj<++y(p-q)}?print:??;