On Mar 17, 3:44 pm, c...@pobox.com (Chap Harrison) wrote:
> On Mar 17, 2011, at 5:21 PM, Rob Dixon wrote:
>
> > A s///g is 'successful' if it performs at least one substitution, in which 
> > case it will return the number of substitutions made. In your code, it will 
> > find as many key=value substrings as possible and replace them with just 
> > the value string.
>
> > The \G pattern is documented only in the case of m//g, which
> > makes sense as it is defined in terms of a character position
> > (pos) within the string where the last match ended.

Um,  the substitution operator  uses  m/// to pattern match
as well so you'll sometimes see \G in s///.

> > If a substitution is being made then it will also affect character
> > positions, and so is similar to adding to or deleting from an array
> > while iterating over it.

No, I don't think so.  Or, am I missing something obvious?
For instance, the char. positions within the original string
being pattern matched are unaffected by s/// replacements:

perl -wle "$_= '123abc4'; s/\G(\d)(?{print pos()})/$1 . 'foo'/
eg;print"
1
2
3
1foo2foo3fooabc4

> ...
>
> > I believe a while loop is the proper way to go, but if you want to 
> > experiment with m//g I suggest something like this
>
> >  my %matches = $line =~ /\G\s*(\w+)(?:\s*=\s*(\w+))?\s*/gc;
>
> > which will pass all the 'key' and 'key=value' pairs to %matches. An invalid 
> > input will cause the match to terminate before the end of the string, so
>
> >  if (pos $line < length $line) {
> >    # code to handle bad input
> >  }
>

Neat solution.  IMO, though, it's much clearer and simpler
(particularly for subsequent maintainers), to identify errors
up front if you can and save the time and complexity to
review \G and pos() and the implication of a  s/// return
count (unless of course you're using them all the time).

   -->  "bad char: $1" if $line =~ / ([^\w=\s]) /x;

> > If a key has no corresponding value in the string it will appear in the 
> > hash with a value of undef, which should be defaulted to 1 like this
>
> >  foreach (values %matches) {
> >    $_ = 1 if not defined;
> >  }
>

You can also use the defined-or operator.

    $_ //= 1 foreach (values %matches)

--
Charles DeRykus


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/


Reply via email to