Perl 5.26, Strawberry on Windows
I'm writing a parser to decode an options file effectively into perl-like assignments. A primitive config might look like:
@arr[2] = 5
var = 10
The example regex block is:
It's obviously in-work, but $1 seems to always be being set to "" if there's no match and not undef as the other values are. For example:sub parse_options { # \%options_we_can_write, \@lines_of_options_fi +le. [ $die_on_extra_options ] #loads all matching values from an array of lines into the options + hash #uses '=' as the separator, one ( 1 ) space on either side my ($options_we_can_write, $options_file_lines, $die_on_extra_opti +ons) = @_; my $var = ""; my $sigil = ""; my $val = ""; my $setter = ""; my $arraything = ""; my $fd = ""; my $rd = ""; my $index = ""; if( ! %{$options_we_can_write} ){ die "no options to match\n" } foreach ( @{ $options_file_lines } ){ if( $_ =~ m/ ^([@%\$]?) # open sigil ([a-zA-Z_]+) # variable (\[)? #optional open bracket ([\d]*) #optional number (])? #optional close bracket \ # space = # equals \ # space ([a-zA-Z0-9_\\\/:]+)$ # string until end of line /x #end regex ){ #startif #print "##$1## ##$2## ##$3## ##$4## ##$5## ##$6##\n"; #com +plains about undefined values if( defined ($sigil = $1) eq "" ){ $sigil = '$' } print "####sigil $sigil ##>$1<##\n"; $var = $2; if( defined ($fd = $3) eq "" ){ $fd = "" }; if( defined ($index = $4) eq "" ){ $index = "" } if( defined ($rd = $5) eq "" ){ $rd = "" }; if ( ($fd eq '[' and $rd ne ']') or ($fd eq "{" and $rd ne + '}') ){ print STDERR "Mismatched delimiters for $var, skipping +\n"; next; } if ( ($fd eq '[' and $rd eq ']') and ( ! is_whole_number($ +index) ) ){ print STDERR "array assignment $var needs whole number + index\n"; next; } # if ($fd eq "{" and $rd != '}' ){ # print STDERR "Error bad delimiter for $var"; # } $setter = "$sigil\{ \$options_we_can_write->{$var} }$fd$in +dex$rd = $val"; print "$setter\n"; if( exists $options_we_can_write->{"$var"} ){ eval $setter; } next; } if( $_ =~ m/^(.*?) = (.*)$/ ){ $var = $1; $val = $2; if( exists $options_we_can_write->{"$var"} ){ ${ $options_we_can_write->{"$var"} } = $val; } else { print "Error: desired option $var not found\n"; } } #print "$_\n"; } return 0; }
can be changed to:if( defined ($fd = $3) eq "" ){ $fd = "" };
and the ssssssss gets shown in 'print $setter' for an assignment without a front-delimiter. I first thought it was because I had "\$" vs '$' but that made no difference. If I explicitly assign $sigil right after the defined line it is assigned, but the else is never executed for $1, unlike $3 and $5. There are no extra characters being passed (\r, \n, etc)if( defined ($fd = $3) eq "" ){ $fd = "ssssssssss" };
In reply to Regex result being defined when it shouldn't be(?) by chenhonkhonk
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |