http://www.perlmonks.org?node_id=943738

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

good $localtime fellow monks,

I am tearing my hair out over a small oddity. Why will this work:

perl -nle "my (@c) = /\:(\w+)\:/g; print join '.', @c" input> out:caputure1:out:capture2:out output> caputure1.capture2

But this behaves so differently

perl -nle "my (@c) = s/\:(\w+)\:/X/g; print join '.', @c" input> out:caputure1:out:capture2:out output> 2

I am trying to extract comments from a file I have in a buffer read in with local $/;. The comments are marked by a ; and continue to the end of the line. For various reasons I want the file as a sinlge line and want to extract the comments. The comments will be added back in later so I substiture them for a marker. I realise I could break the file into lines and put it back together again later but I would love to be able to do it in one line

Cheers,
R.

Pereant, qui ante nos nostra dixerunt!

Replies are listed 'Best First'.
Re: s///g and capturing all matches
by johngg (Canon) on Dec 15, 2011 at 15:06 UTC

    Rather than a global match you could use a while statement modifier.

    knoppix@Microknoppix:~$ perl -E ' > $file = <<EOD; > some data; comment 1 > more data; comment 2 > even more data; comment 3 > EOD > push @comments, $1 while $file =~ s{(;[^\n]*)}{*MARKER*}; > say $file; > say for @comments;' some data*MARKER* more data*MARKER* even more data*MARKER* ; comment 1 ; comment 2 ; comment 3 knoppix@Microknoppix:~$

    I hope this is of interest.

    Cheers,

    JohnGG

      Hi JohnGG,

      I had tried the while but could not get the syntax right. Thanks for pointing me down the right path.

      Cheers,
      R.

      Pereant, qui ante nos nostra dixerunt!
Re: s///g and capturing all matches
by Anonymous Monk on Dec 15, 2011 at 14:26 UTC

      thank you anonymonk, very ellegant. I had forgoton the use of code in the RHS was possible.

      Cheers,
      R.

      Pereant, qui ante nos nostra dixerunt!
Re: s///g and capturing all matches
by jethro (Monsignor) on Dec 15, 2011 at 14:27 UTC

    To quote the documentation of s/// it " returns the number of substitutions made". You made two substitutions, so the result is 2

      Hi Jethro,

      and the answer to life, the universe and everything is 42 ;)

      I was wondering why the implementations differ, as well as seeking an ellegant way to get the behaviour I wanted. If s///; returned a list of the items sub'd out then it would be easy enough to use that in scalar contect to have the number. Felt rather un-Perlish to miss out on potential utility.

      Cheers,
      R.

      Pereant, qui ante nos nostra dixerunt!