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

Hello Monks, I'm a total noob to perl and programing in general, and would appreciate any help to achieve what i want, and all i want is just a simple script that can be applied to any file and does two things.

first, find a matched number and replace it with a calculated value.
second, is to find a matched string and add the number of occurrence to it.

for example,

1- find the Z value and multiply it by 4:

Z=5, and to be replaced by Z=20,

2- find the XP word and add the number of occurrence to it:

Ah, so fondly I remember when I became a PerlMonks member, And in my innocence never posted purely to be an XP Whore. Happily your code I’d borrow, and back again I’d be tomorrow Though some examples left me harrowed, harrowed and synapses sore, for my ignorance was abundant and my knowledge of the language poor, But now I’m just an XP Whore.

and to be replaced with:

Ah, so fondly I remember when I became a PerlMonks member, And in my innocence never posted purely to be an XP (1) Whore. Happily your code I’d borrow, and back again I’d be tomorrow Though some examples left me harrowed, harrowed and synapses sore, for my ignorance was abundant and my knowledge of the language poor, But now I’m just an XP (2) Whore.

i did some search and that's what i found but i'm stuck and can't go any further.
$^I = '.bak'; while (<>) { s/Z=(\d+),/ what do i do here? /g; s/\bXP\b/ what do i do here? /g; print }

Replies are listed 'Best First'.
Re: How to find a number and replace it with calculated value?
by toolic (Bishop) on Mar 03, 2017 at 13:19 UTC
    Use the 'e' modifier for s///
    use warnings; use strict; while (<DATA>) { s/(Z=)(\d+)/$1 . $2*4/eg; my $i = 1; s/\b(XP)\b/$1 . ' (' . $i++ . ')'/eg; print; } __DATA__ Z=1 Z=2 Z=3 foo XP bar XP boo

    Outputs:

    Z=4 Z=8 Z=12 foo XP (1) bar XP (2) boo
      Thanks toolic, that's what i wanted. just a small issue, the increment of occurrence number is per line, how to make it per file or multipleline?
        ... the increment of occurrence number is per line, how to make it per file or multipleline?

        Move the  my $i = 1; statement to before the loop (untested):

        my $i = 1; while (<DATA>) { ... s/\b(XP)\b/$1 . ' (' . $i++ . ')'/eg; print; }


        Give a man a fish:  <%-{-{-{-<

Re: How to find a number and replace it with calculated value?
by AnomalousMonk (Archbishop) on Mar 03, 2017 at 21:44 UTC

    The multi-pass approach used by toolic here is effective and sane. But if you really want to over-engineer the heck out of this problem, you could move all the parsing and string generation off to a module, which could be quite simple, not even exporting anything:
    Module Lame.pm:

    Invocation:
    c:\@Work\Perl\monks\Lejocode>perl -wMstrict -le "use Lame; ;; my $s = 'a Z=4 b ZZ=1 c Z = 123Z=99d XP e XXPP f XP gXPh'; print qq{'$s'}; ;; Lame::parse(\$s); print qq{'$s'}; " 'a Z=4 b ZZ=1 c Z = 123Z=99d XP e XXPP f XP gXPh' 'a Z=20 b ZZ=1 c Z = 615Z=495d XP (1) e XXPP f XP (2) gXP (3)h'

    Update: Lame.pm should probably also include a setter for $n_XP:
        sub set_XP { $n_XP = $_[0]; }


    Give a man a fish:  <%-{-{-{-<

      That's a bit advanced for my current knowledge (if there's any), but i'm gonna save it, and gonna read some tutorials and try to figure it out. Thanks AnomalousMonk.