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

Have repeatedly searched the web for the answer but could not find Anything. Did find this unanswered question however which is exactly what I have tried. So i thought id try here.

I have found a couple of ways of replacing text within an array, but can't get either of them to work. This would point to human error, but I can't see where I'm going wrong:

(1)

@config = map {s/oldtext/newtext/g; $_; } @config; for $t (0 .. $#config) { print"$config[$t][0]\n"; }

This doesn't produce the expected results though, as the oldtext remains and has not been changed at all.

(2) The 2nd approach I have tried is:

for (@config) {s/oldtext/newtext/g}

and when I print this out using the same bit of code as above, this doesn't work either.

So can somebody please tell me how I can replace text within an array (each element is a line of text)??? thanks!

Replies are listed 'Best First'.
Re: String substitution inside an array
by NetWallah (Canon) on Sep 09, 2011 at 04:42 UTC
    First - working code:
    use strict; use warnings; my @config = qw|this oldtext needs replacement but not newtext Just ol +dtext|; for (@config) { s/oldtext/newtext/ } print qq|$_;\n| for @config; # "Perl" style print for my $t (0 .. $#config){ # Your style (c-style for loop) print "$t:$config[$t];\n"; }
    Now - the stuff that appears not to have worked for you:
    @config = map {s/oldtext/newtext/g; $_; } @config;
    This works, but is way overkill.

    First, omit the "@config =".

    Then omit the $_. This works as well:

    map {s/oldtext/newtext/g; } @config;
    but then you may as well use the simpler:
    s/oldtext/newtext/ for @config;
    Which avoids generating a throw-away array, and is almost the same as your second attempt. (I would not use the "g" modified unless you were expecting multiple instances of the search string in one element of the array.)

    Your print loop is attempting to apply two indexes to a single-dimension array.

                "XML is like violence: if it doesn't solve your problem, use more."

      Thanks. That helps alot.

      "Which avoids generating a throw-away array"

      Thats exactly how i was going to solve it :). Build another array and replace. Thought about it after i posted.

        P.s. "XML is like violence: if it doesn't solve your problem, use more."

        Love that :)

Re: String substitution inside an array
by AnomalousMonk (Archbishop) on Sep 09, 2011 at 13:29 UTC

    The print statement
        print"$config[$t][0]\n";
    in the print loop of example (1) of the OP suggests the possibility* you are dealing not with an array of strings, but with an array of array references each of which has at least one element, the first, that is a string.

    If this is so, the following code addresses this case, both with more and less redundant, as NetWallah has pointed out, map approaches, and with a more 'standard' for-loop.

    >perl -wMstrict -le "my @config = ([ 'fee fie' ], [ 'foe'], [ 'fum' ],); printf qq{'$_->[0]' } for @config; print ''; ;; @config = map { $_->[0] =~ s{(f[eio]e)}{\u$1}xmsg; $_; } @config; printf qq{'$_->[0]' } for @config; print ''; ;; map { $_->[0] =~ s{ (F [eio] e) }{\U$1}xmsg } @config; printf qq{'$_->[0]' } for @config; print ''; ;; for my $ar (@config) { $ar->[0] =~ s{ (F [EIO] E) }{\L$1}xmsg;; } printf qq{'$_->[0]' } for @config; print ''; " 'fee fie' 'foe' 'fum' 'Fee Fie' 'Foe' 'fum' 'FEE FIE' 'FOE' 'fum' 'fee fie' 'foe' 'fum'

    * I know this is a possibility because if you had been dealing with an array of simple strings, you would have seen an error or a bunch of warnings because, of course, you're running with strictures and warnings enabled.