in reply to changing only the first two matches of a regex

Hint: use anchors.

With your example, it appears you want to get rid of the first two digits and their following underscores that appear in the string. A regex that does that is:

$string =~ s/^\d_(\D+?)\d_(.*)/$1$2/;

the caret "^" at the beginning of this regex anchors things to the beginning of the string. You then make judicious use of captures to get the desired result.

Philosophy can be made out of anything. Or less -- Jerry A. Fodor

Replies are listed 'Best First'.
Re: Re: changing only the first two matches of a regex
by mirod (Canon) on Mar 20, 2001 at 19:54 UTC

    Actually this will not work if the string includes numbers in the part that you match with \D. I think you have to "unroll the loop" if you want to avoid (.*?):

    #!/bin/perl -w use strict; foreach( <DATA>) { s{^\d+_ # start then number(s) then _ ((?:\D*(?:\d(?!\d*_))?)*) # non_digits then optionnaly # a digit _not_ followed by dig +its and _ # repeat, rince... \d+_ # the second digit _ sequence (.*)} # the rest of the string {$1$2}x; print; } __DATA__ 1_abc/2_deg/bla_30_31_blah 1_ab1c/2_deg/bla_30_31_blah 1_ab1c/22_deg/bla_30_31_blah 1_a2b33c/22_deg/bla_30_31_blah a_ab1c/b_deg/bla_30_31_blah

    Note that your regexp will not work properly for the second string. I also added a line where the regexp does not match as this can show bugs when a badly written regexp takes for ever to match on a string that it does not match.

    Frankly it this case, and despite all the warnings around, I would use (.*?) and write the regexp as:

    s/^\d_(.*?)\d_(.*)/$1$2/;

    I would be happy to get enlightened as to why this is not safe by the way.