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

Monks!

I have a string I need to parse for parameters. So I have written the following code:

#!/usr/contrib/bin/perl # Parses a string in the format: # REFDATA_ERROR[type=<1>,system=<2>,category=<3>,code=<4>] # Prints out the four parameters, <1>, <2>, <3>, <4> sub parse_error($) { $params =~ m/REFDATA_ERROR\[type=(.*),system=(.*),category=(.*),code +=(.*)\]/; print "$params\n"; print "$1\n"; print "$2\n"; print "$3\n"; print "$4\n"; } # Main parse_error("REFDATA_ERROR[type=val1,system=val2,category=val3,code=va +l4]");

... only problem is my print statements are just returning blanks. Can anyone point me in the right direction please?

____________
Arun

Replies are listed 'Best First'.
Re: Parsing with Regular Expressions
by Corion (Patriarch) on Nov 17, 2004 at 14:57 UTC

    Always check whether your regular expression matched before accessing the capture variables $1, $2 ...:

    #!/usr/contrib/bin/perl # Parses a string in the format: # REFDATA_ERROR[type=<1>,system=<2>,category=<3>,code=<4>] # Prints out the four parameters, <1>, <2>, <3>, <4> sub parse_error { $params =~ m/REFDATA_ERROR\[type=(.*),system=(.*),category=(.*),code +=(.*)\]/ or die "The input string was invalid: '$params'"; print "$params\n"; print "$1\n"; print "$2\n"; print "$3\n"; print "$4\n"; }; # Main parse_error("REFDATA_ERROR[type=val1,system=val2,category=val3,code=va +l4]");

    If you had used strict, Perl would have told you that your variable $params is undefined, as you seem to have a misconception on how parameters are passed around in Perl. The input parameters to your function live in the @_ array. Also, you are using a prototype on your sub declaration, which is in most cases a bad thing to do unless you know what you're doing (you don't).

      use strict; would have told that $params is undeclared; use warnings; would have told that it is undefined.

      While both should be used for almost all code, warnings is the more important of the two to mention IMO.

Re: Parsing with Regular Expressions
by tilly (Archbishop) on Nov 17, 2004 at 16:22 UTC
Re: Parsing with Regular Expressions
by dragonchild (Archbishop) on Nov 17, 2004 at 15:31 UTC
    Additionally, you might want to look at using .*? instead of .*, depending on the string you're handling.

    Another option to parsing might be doing something like:

    sub parse_error($) { my $error = shift; my $values = $error =~ /\[([^\]]*)\]/; my %values; foreach my $param (split /,/, $values) { my ($k, $v) = split /=/, $param; $values{$k} = $v; } return %values; }

    Being right, does not endow the right to be rude; politeness costs nothing.
    Being unknowing, is not the same as being stupid.
    Expressing a contrary opinion, whether to the individual or the group, is more often a sign of deeper thought than of cantankerous belligerence.
    Do not mistake your goals as the only goals; your opinion as the only opinion; your confidence as correctness. Saying you know better is not the same as explaining you know better.

      Or better yet, use ([^,]+) (see Death to Dot Star!).

      m/REFDATA_ERROR\[ type=([^,]+), system=([^,]+), category=([^,]+), code=([^\]]+) \]/x; # The /x added for readability

      The intelligent reader will judge for himself. Without examining the facts fully and fairly, there is no way of knowing whether vox populi is really vox dei, or merely vox asinorum. -- Cyrus H. Gordon