Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options

Substitution problem.

by Leitchn (Acolyte)
on Nov 25, 2000 at 05:22 UTC ( #43279=perlquestion: print w/replies, xml ) Need Help??

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

I'm trying to increment through two arrays of characters, replacing one with the other throughout a piece of text. My problem comes when one of these is a [.
Perl throws it out as an unmatched open bracket. Quotemeta doesn't help, so any ideas?

Here's my code:

for $count(0..52){

$someText =~ s/quotemeta('$array1{$count}')/quotemeta('$array2{$co +unt}')/g;




Replies are listed 'Best First'.
Re: Substitution problem.
by Dominus (Parson) on Nov 25, 2000 at 05:48 UTC
    You think you're using quotemeta, but you aren't. Instead, you are telling Perl to look for a string that begins with a q followed by a u and soforth. Perl does not evaluate arbitrary expressions on the left side of s///.

    Try this:

    for $count (0..52) { my $pattern = quotemeta($array1{$count}); $sometext =~ s/$pattern/$array2{$count}/g; }
    Or (does the same thing):
    for $count (0..52) { $sometext =~ s/\Q$array1{$count}/$array2{$count}/g; }
    Notice also: No ' single quotes around variable names, because single quotes prevent variables from being interpolated. Also no quotemeta on the right side, because it is not necessary.

Re: Substitution problem.
by snax (Hermit) on Nov 25, 2000 at 20:13 UTC
    Why don't you try to do this more "all at once"?

    First, note that tr/// is the right tool for single character substitution lists -- it's heavily optimized for this kind of thing.

    Second, it seems to me that your $count variable may be redundant. Why not make one hash with keys the "old" values and the values the "new" values -- that sounds odd, but basically:

    $replacements{quotemeta($array1{$count})} = $array2{$count};
    ...but do this where you are building %array1 and %array2 so you don't need to use $count or the array hashes at all. Aside: in perl's common parlance, "array" typically refers to an integer indexed object like you are using your hashes above, but the hash construct is much more flexible (and more expensive to use in terms of resources).

    Anyway, with a %replacements hash you can then do:

    my $repl_str = join( '|', keys %replacements); $someText =~ s/($replstr)/%replacements{$1}/g;
    This does all your replacements with one evaluation.

    Again, note that this is really only appropriate when you need to replace more than single characters.

Re: Substitution problem.
by Fastolfe (Vicar) on Nov 25, 2000 at 05:45 UTC
    First of all, you're only using the /g flag, which will interpret your expressions literally and do interpolation. So you end up with this:
    Which presumably (if it were valid) would match the text "quotemeta'['", putting '[' into $1. Try doing this:
    Or, if each array element simply has one character apiece (as you suggest), forego the loop entirely and use tr:
    $from = join('', @array1); # or set up $from and $to $to = join('', @array2); # to begin with tr/$from/$to/; # e.g. "abc" =~ tr/ab/xy/ ==> "xyc"
      Says fastolfe:
      > tr/$from/$to/;
      This won't work, because variables are not interpolated inside of tr///. Your line replaces $ with $; f with t; and r, o, and m with o.
        Indeed, so that one would want to use:
        More and more the only place I end up using eval is in this type of construction.

Log In?

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

How do I use this? | Other CB clients
Other Users?
Others having an uproarious good time at the Monastery: (2)
As of 2022-12-03 06:15 GMT
Find Nodes?
    Voting Booth?

    No recent polls found