Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

Replace strings with []

by jess195 (Novice)
on Oct 13, 2013 at 12:06 UTC ( [id://1058066]=perlquestion: print w/replies, xml ) Need Help??

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

Hello all,

I have a string that is equal to:

my $str = Hello world a[0]! a wonderful experience.

And I need to replace all occurrence of a[0] to a random number from a map. So what I do is the following:

 my @arr = ("a", "a[0]", "b", "b[0]");

I have a map that maps each of the above variables to a random number. My problem is when I try the following:

foreach (@arr) { $str =~ s/($_)/random{$1}/g; #where random is my map}

Non of the a[0] gets replaced with its value from the map, instead with the value of a. Any idea how to fix this in perl?

Replies are listed 'Best First'.
Re: Replace strings with []
by Corion (Patriarch) on Oct 13, 2013 at 12:09 UTC

    See quotemeta.

    Your a[0] is a valid regular expression and means "match an a, and then match a zero. quotemeta is what you need to make a literally matching string of your variable.

      It works... Thanks!

Re: Replace strings with []
by Tanktalus (Canon) on Oct 14, 2013 at 04:03 UTC

    I seem to recall someone saying at one point that it's a rite of passage, everyone implements a templating language, usually badly. It starts out simple enough, but then grows into some unmaintainable behemoth that is inconsistent, slow, and ugly.

    So, what I'm trying to say, is that if you have any control over that string, try re-using existing templating languages instead of inventing your own. Depending on what you're doing, you may find this actually is more expensive than doing it yourself. But, in my experience, that doesn't hold true for long. The cost of adding features to a hand-rolled templating system that weren't thought of when you started can grow very quickly.

    At $work, in my current project, I elected to do a hybrid. At first, I simply used my own templating code due to legal reasons (getting legal approval to ship wasn't going to be soon enough). However, I wrote it to work with the subset of Template Toolkit that was sufficient for my needs at the time. By the time I needed more, I had legal approval to use and ship Template Toolkit (under the Artistic license), and none of my templates needed changing, while I simply had to swap out my code for the more generic Template Toolkit, and I got all the extra features I needed (and many more I didn't ... yet).

    So, even if you don't want to go full-tilt into a module's template code, may I at least suggest being compatible with the subset of the language you do need? It'll make it easier to switch should you ever need more, and may make other things more obvious. Such as using [% random_hash("a[0]") %] instead of just a[0]?

    Of course, maybe you have no control or influence over your input, and that's unfortunate. In that case, continue with your current approach. Just be aware that if you have different keys of different length and some may be subsets of another, you'll also want to sort them by length and try the longest ones first. (This isn't always straightforward if your match strings actually have variable length modifiers, such as * or ? in there.) And, of course, if a[0]'s result includes "a" in its output, things can get wonky (though you said that a[0] would result in a number, so you should be fine with the example data).

    Good luck!

Re: Replace strings with []
by hdb (Monsignor) on Oct 14, 2013 at 06:52 UTC

    I'm wondering about the order of elements in @arr. From the code below it seems that you will first replace all a's with random{$1} (should it be $random{$1}?) and then look for a[0]. But if all a's have been replaced by something else you will not find any a[0]'s anymore. What is the underlying logic behind this order?

Re: Replace strings with []
by ainkov (Novice) on Oct 14, 2013 at 06:41 UTC

    I believe another option is to use \Q and \E in your regular expression.
    This will "quote (disable) pattern metacharacters till \E":

    $str =~ s/\Q$_\E/$random{$_}/g;

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others imbibing at the Monastery: (5)
As of 2024-03-28 14:22 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found