On Mar 16, 9:58 am, c...@pobox.com (Chap Harrison) wrote:
> Oops, I misplaced the final closing parenthesis in the regex.  But it doesn't 
> seem to matter.
>
> - - - - -
>
> #!/usr/bin/perl
>
> use warnings;
> use strict;
> use feature ":5.10";
>
> #
> # $line, unless empty, should contain one or more white-space-separated
> # expressions of the form
> #       FOO
> # or    BAZ = BAR
> #
> # We need to parse them and set
> # $param{FOO} = 1       # default if value is omitted
> # $param{BAZ} = 'BAR'
> #
> # Valid input example:
> #   MIN=2 MAX = 12  WEIGHTED TOTAL= 20
> # $param{MIN} = '2'
> # $param{MAX} = '12'
> # $param{WEIGHTED} = 1
> # $param{TOTAL} = '20'
> #
>
> my $line = 'min=2 max = 12 weighted total= 20';
> $line = 'min=2 max, = 12 weighted total= 20';
> say $line;
> my %param;
>
> if ( $line and
>      ($line !~
>            s/
>                 \G            # Begin where prev. left off
>                 (?:           # Either a parameter...
>                     (?:            # Keyword clause:
>                         (\w+)      # KEYWORD (captured $1)
>                         (?:        # Value clause:
>                             \s*    #
>                             =      # equal sign
>                             \s*    #
>                             (\w+)  # VALUE (captured $2)
>                         )?         # Value clause is optional
>                     )
>                     \s*            # eat up any trailing ws
>                 )             ### <-- moved
>                 |             # ... or ...
>                     $         # End of line.
>             /                 # use captured to set %param
>                 $param{uc $1} = ( $2 ? $2 : 1 ) if defined $1;
>        /xeg
>    ) ) {
>     say "Syntax error: '$line'";
>     while (my ($x, $y) = each %param) {say "$x='$y'";}
>     exit;}
>
> while (my ($x, $y) = each %param) {say "$x='$y'";}

I believe the problem is the "?   # Value clause is optional"
since, in the case of your badline with a ",", the regex will
consume 'max' and then ignore the , since ? means 0 or 1
instance.  Therefore the regex will still succeed and $2 will
be undefined. So the VALUE gets set to 1.

Rather than crafting a still more complicated regex, a
quick fix might be a pre-check  to see if the line has any
character that's not a \w, =, or whitespace:

    # disallow anything but equal, word, or whitespace

    die "Syntax error: found disallowed char:$1"
        if  $line =~ /([^=\w\s])/);

    #  continue to process line...
    if ( $line and  $line !~  ....

--
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