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

hi, I am trying to use non-capturing grouping (?:) in an replacement:
my $str = 'hello kitty 003x009 spanish'; $str =~ s/^(?:hello kitty )(\d+)(?:x\d+.*)$/sprintf "%d", $1/e; print $str; # result: 3 # expected: 'hello kitty 3x009 spanish'
I tought that non-capturing grouping maybe does not work with evaluation modifier 'e' but that was not problem:
$str =~ s/^(?:hello kitty )(\d+)(?:x\d+.*)$/XX/;
produces 'XX' as result. does non-capturing work when replacing?

Replies are listed 'Best First'.
Re: regexp: non-capturing grouping in replacement possible?
by moritz (Cardinal) on Nov 26, 2009 at 12:50 UTC
    You need look-around assertions, not non-capturing groups. See perlre, search for positive look-ahead assertion and zero-width positive look-behind assertion.

    A substitution substitutions not only the captured part of the string, but the matched part of the string. Using zero-width assertion you can reduce the matched part of the string to the captured part.

      I forgot to mention that I tried it but either I am doing something wrong or ...:
      $str =~ s/(?=hello kitty )(\d+)/sprintf "%d", $1/e;
      does not do anything. it is probably me but I don't see it.
        ?= is look ahead. try ?<= (look behind)
Re: regexp: non-capturing grouping in replacement possible?
by JavaFan (Canon) on Nov 26, 2009 at 13:31 UTC
    I'd write that as (untested):
    s/^hello kitty \K0*([1-9][0-9]*)(?=x[0-9])/$1/;
    It seem that all you want to do is remove leading 0s.
Re: regexp: non-capturing grouping in replacement possible?
by biohisham (Priest) on Nov 26, 2009 at 14:13 UTC
    Can not a simpler approach give you what you're looking for? capture the 3 which is preceded by 0s, remove those 0s and preserve the 3..
    my $str = 'hello kitty 003x009 spanish'; $str =~ s/0*(3)/$1/; print $str;


    Excellence is an Endeavor of Persistence. Chance Favors a Prepared Mind.
      thanks but it is not about zeros but about learning. I could remove zeroes with a simple 0*.
      $str =~ s/^(hello kitty )0*(\d+)(x\d+.*)$/$1$2$3/;
        learning? this one also removes any leading zero of number after "hello kitty" :-)
        s/(?<=hello kitty )0*(?=\d(?!\d))//
        Update: oops, small mistake, \b replaced with (?!\d)