I'm trying to write a routine to parse a string containing a series of 
parameters of the form 

KEYWORD = VALUE 
or just 
KEYWORD  (where the value defaults to 1)

I was able to write it using a WHILE loop, but then thought I'd try using the 
'g' option of s/// to do the iteration.

It seems to parse correctly-formed strings fine, but it is not *failing* to 
match an incorrectly-formed string.

The following is what I've got so far.  $line is set to a valid string, while 
$badline is set to an invalid one - which, nevertheless, is parsed (partially) 
as valid.

(Incidentally, as I post this I don't know whether my lines will be 
hard-wrapped at some ridiculous length like 60, thus screwing up the code by 
wrapping my regex comments.  What causes that to happen? and, more to the 
point, is that something I can override in my POP client?)

Also - if there's a module I should be using instead of re-inventing the wheel, 
I'd appreciate knowing about it.  But in any event, I'd like to understand why 
my approach isn't working.

Here's the code.  Thanks for any help.
Chap

- - - - -

#!/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
# Yields:
# $param{MIN} = '2'
# $param{MAX} = '12'
# $param{WEIGHTED} = 1
# $param{TOTAL} = '20'
#

my $line = 'min=2 max = 12 weighted total= 20';
my $badline = 'min=2 max, = 12 weighted total= 20';

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
                |             # ... 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'";}


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