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

Hi, I've been trying to figure this out for ages, but just can't see a way to do it. I need to replace certain digits in a string with the contents of a variable, however those digits may also appear elsewhere in the string and I need to only replace the digits in the exact location specfified. For example I need to search for the match below in my string and replace 99 (as assigned to speacial variable $1) with the contents of my variable. I do not want to replace the last 99 in the pattern match with the contents of my variable
$line = "0165451234599123459935589"; $line =~ s/12345(99)1234599/$replace/;
Is this even possible do to in a nice succinct one liner?

Replies are listed 'Best First'.
Re: Specific substitution in regular expressions
by moritz (Cardinal) on Sep 17, 2008 at 10:08 UTC
    What I do in cases like this is to use look-around assertions:
    s/(?<=12345)99(?=1234)/$variable/g;

    Of course no /g is needed when only one instance should be replaced.

      Thanks guys. The look ahead / behined assertion method and breaking down the regex in to more matches look like what I need.
Re: Specific substitution in regular expressions
by svenXY (Deacon) on Sep 17, 2008 at 09:43 UTC
    Hi,
    if you were just after the first '99' in your string, just omit the 'g'-Modifier, otherwise use more groupings to do it:
    my $reg = '99'; my $replace = 'XX'; my $line = "0165451234599123459935589"; print $line, "\n"; $line =~ s/$reg/$replace/; print $line, "\n"; $line = "0165451234599123459935589"; $line =~ s/(12345)($reg)(12345)/$1$replace$3/; print $line, "\n";
    prints
    0165451234599123459935589 01654512345XX123459935589 01654512345XX123459935589

    Regards,
    svenXY
Re: Specific substitution in regular expressions
by apl (Monsignor) on Sep 17, 2008 at 09:48 UTC
    substr( $line, index( $line, '99' ), 2 ) = $variable;
    The 2 being the length of '99'.
      Hi,
      ++apl, works fine as long as the '99' the OP wants to replace is really the first occurence of '99' in the string.
      Regards,
      svenXY
Re: Specific substitution in regular expressions
by jonadab (Parson) on Sep 17, 2008 at 10:20 UTC

    Lookbehind and lookahead will work in the specific example you give, but the more general solution, which will still work if the surrounding stuff can vary in width, is to capture the surrounding stuff and substitute it back:

    $line =~ s/(12345)(99)(1234599)/$1$replace$3/;
    -- 
    We're working on a six-year set of freely redistributable Vacation Bible School materials.