in reply to regexp - replace spaces in quoted string

My thanks to you both. To help with my regexp education, would you mind expanding a little on the syntax?
  • Comment on Re: regexp - replace spaces in quoted string

Replies are listed 'Best First'.
Re^2: regexp - replace spaces in quoted string
by planetscape (Chancellor) on Sep 06, 2005 at 10:43 UTC

    YAPE::Regex::Explain will help you:

    The regular expression: (?-imsx:s/(".*?")/($x=$1)=~y: :_:, $x/ge) matches as follows: NODE EXPLANATION ---------------------------------------------------------------------- (?-imsx: group, but do not capture (case-sensitive) (with ^ and $ matching normally) (with . not matching \n) (matching whitespace and # normally): ---------------------------------------------------------------------- s/ 's/' ---------------------------------------------------------------------- ( group and capture to \1: ---------------------------------------------------------------------- " '"' ---------------------------------------------------------------------- .*? any character except \n (0 or more times (matching the least amount possible)) ---------------------------------------------------------------------- " '"' ---------------------------------------------------------------------- ) end of \1 ---------------------------------------------------------------------- / '/' ---------------------------------------------------------------------- ( group and capture to \2: ---------------------------------------------------------------------- $ before an optional \n, and the end of the string ---------------------------------------------------------------------- x= 'x=' ---------------------------------------------------------------------- $ before an optional \n, and the end of the string ---------------------------------------------------------------------- 1 '1' ---------------------------------------------------------------------- ) end of \2 ---------------------------------------------------------------------- =~y: :_:, '=~y: :_:, ' ---------------------------------------------------------------------- $ before an optional \n, and the end of the string ---------------------------------------------------------------------- x/ge 'x/ge' ---------------------------------------------------------------------- ) end of grouping ----------------------------------------------------------------------

    HTH,


    Update: See below for corrections. (Thanks, japhy!)

    planetscape
      s/(".*?")/($x=$1)=~y: :_:, $x/ge) [CUT] =~y: :_:, '=~y: :_:, ' ---------------------------------------------------------------------- $ before an optional \n, and the end of the string ---------------------------------------------------------------------- x/ge 'x/ge'
      Hm... Is it good explanation??
      I'll try in my poor english:
      s/(".*?")/($x=$1)=~y: :_:, $x/ge) ^^^^^^^^^1 ^^^^^^^2 ^^^^^^^3 ^^4 ^^^5
      1) take ALL between " and "
      2) So you have ALL in $1. $1 is read only, so copy $1 to $x. And now, for one moment forget about all and work only on $x (this is thanx /e which "wraps an eval{...} around the replacement string and the evaluated result is substituted for the matched substring".
      3)in $x replace all ' ' to '_'
      4)put replaced $x into first s/from/to/
      5)g - works globaly; e - eval the replacment string

      greets
      Uksza

        While the explanation provided by YAPE::Regex::Explain will probably be inferior to that which a human well-versed in regexps could produce, the advantage in using the module is that an explanation can be produced without having access to the well-versed human. It is available to anyone with access to CPAN, and therefore can be quite useful to the learner. :-)

        planetscape
Re^2: regexp - replace spaces in quoted string
by intel (Beadle) on Sep 06, 2005 at 10:55 UTC
    To explain the first response syntax:
    #declarations my ($quote_on,$output); #default scalar is the data $_ = q/this is a "test of some regexp" blah blah this is another "test of some regexp" foo bar/; #using $_ begin a for loop performing a split on each #element for (split //) { #quote_on is a boolean set to true when the increments reach #a quote (and then off again when reaching another quote) $quote_on = ($quote_on ? 0 : 1) if (/\"/); #if processing elements after a quote, then replace the #whitespace with an underscore s/\s/_/g if $quote_on; #assign all that to $output $output .= $_; }
    I didn't write the original post, but I was thinking about doing it a different way, although this one seems to be
    perfectly adequate and more importantly, maintainable, than a seemingly more elegant one-liner. Just IMHO