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

Hi,

in the code below I try to put in single quotes all the numbers in the second set of parenthesis of $string.

However, the s///g command does not seem to act on the g modifier.

Who has got some clues?

Thanks.

$string = "(1,2,3) XXX (1,2,3)"; for ($string) { s/XXX \(/XXX \('/; s/(XXX [^,]+),/$1';'/g; s/;/,/g; s/\)$/'\)/; } print $string, "\n"; # Produces output: (1,2,3) XXX ('1','2,3')

Replies are listed 'Best First'.
Re: Need help with substitue /g
by Anonymous Monk on Apr 11, 2010 at 10:12 UTC
    Run your program with
    perl -Mre=debug prog.pl
    and you'll get clues Basically the pattern you're matching only occurs one time.
Re: Need help with substitue /g
by jwkrahn (Abbot) on Apr 11, 2010 at 15:29 UTC
    my $string = "(1,2,3) XXX (1,2,3)"; $string =~ s{(?<=XXX )(\(.*?\))}{ (my $x = $1) =~ s/(\d+)/'$1'/g; $x } +e; print "$string\n";
Re: Need help with substitue /g
by Anonymous Monk on Apr 11, 2010 at 10:17 UTC
Re: Need help with substitue /g
by johngg (Canon) on Apr 11, 2010 at 23:37 UTC

    Rather than a repeated global match you could capture what's inside the second set of parentheses and then use split, map and join to modify it in one go. (Note that I use the hex value for a single quote because I am running this as a one-liner in a *nix shell; you wouldn't need to do that inside a script.)

    $ perl -E ' > $_ = q{(1,2,3) xxx (1,2,3)}; > s{([^(]+)(?=\)$)}{ join q{,}, map qq{\x27$_\x27}, split m{,}, $1 }e; > say;' (1,2,3) xxx ('1','2','3') $

    I hope this is of interest.

    Cheers,

    JohnGG

Re: Need help with substitue /g
by 7stud (Deacon) on Apr 12, 2010 at 05:24 UTC

    Another way:

    use strict; use warnings; use 5.010; use Readonly; Readonly my $SPACE => q{ }; my $string = "(1,2,3) XXX (1,2,3)"; my @pieces = split $SPACE, $string; $pieces[-1] =~ s{(\d)}{'$1'}g; my $new_string = join $SPACE, @pieces; say $new_string; --output:-- (1,2,3) XXX ('1','2','3')
Re: Need help with substitue /g
by JavaFan (Canon) on Apr 12, 2010 at 10:59 UTC
    use 5.010; use strict; use warnings; my $string = "(1,2,3) XXX (1,2,3)"; my $open = -1; $open = index $string, "(", $open + 1 for 1 .. 2; my $close = index $string, ")", $open + 1; substr($string, $open + 1, $close - $open - 1) =~ s/(\d+)/'$1'/g; say $string; __END__ (1,2,3) XXX ('1','2','3')
Re: Need help with substitue /g
by AnomalousMonk (Archbishop) on Apr 12, 2010 at 11:01 UTC

    This may be overkill, but here's an approach to controlling which of several parenthesized digit groups gets its digits quoted (requires  \K from 5.10):

    use warnings; use strict; my $paren_grp = qr{ \( \d+ (?: , \d+)* \) }xms; my $non_paren = qr{ [^(] }xms; for my $n (0 .. 3) { my $s = '(1) XXX (123) YY YY (1,22,333) Z Z Z (22,1)'; $s =~ m{ \A $non_paren* (?: $paren_grp $non_paren*){$n} \( }xmsg; $s =~ s{ \G ,? \K (\d+) }{'$1'}xmsg; print qq{skip $n :$s: \n}; }

    Output:

    skip 0 :('1') XXX (123) YY YY (1,22,333) Z Z Z (22,1): skip 1 :(1) XXX ('123') YY YY (1,22,333) Z Z Z (22,1): skip 2 :(1) XXX (123) YY YY ('1','22','333') Z Z Z (22,1): skip 3 :(1) XXX (123) YY YY (1,22,333) Z Z Z ('22','1'):

    Update: I think it should be possible to integrate the two-step  m//g; s///g; approach entirely into a single  s///g; regex (possibly using 5.10's backtracking control verbs), but I can't quite figure out how – and I'm not sure it would be worth the effort except to satisfy my curiosity!