in reply to Non-greedy substitution

$test =~ s/,(.+?)$/ and$1/; ALWAYS goes to the first comma and the rest is anchored to the end of the line so it will always match everything to the end of the line. Without the anchor it would match the next character after the comma (the space character.)

There are a few different ways to match the last comma:

$ perl -le'my @x = ( "A", "A, B", "A, B, C" ); # 1a for my $test ( @x ) { $test =~ s/(.*),/$1 and/s; print $test; } ' A A and B A, B and C $ perl -le'my @x = ( "A", "A, B", "A, B, C" ); # 1b for my $test ( @x ) { $test =~ s/.*\K,/ and/s; print $test; } ' A A and B A, B and C $ perl -le'my @x = ( "A", "A, B", "A, B, C" ); # 2a for my $test ( @x ) { $test =~ s/,([^,]*)\z/ and$1/; print $test; } ' A A and B A, B and C $ perl -le'my @x = ( "A", "A, B", "A, B, C" ); # 2b for my $test ( @x ) { $test =~ s/,(?=[^,]*\z)/ and/; print $test; } ' A A and B A, B and C $ perl -le'my @x = ( "A", "A, B", "A, B, C" ); # 3 for my $test ( @x ) { $test = reverse $test; $test =~ s/,/dna /; $test = reverse $test; print $test; } ' A A and B A, B and C

Which one you use will depend on how much data you have to process.

Naked blocks are fun! -- Randal L. Schwartz, Perl hacker