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:

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; }
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:
if( defined ($fd = $3) eq "" ){ $fd = "" };
can be changed to:
if( defined ($fd = $3) eq "" ){ $fd = "ssssssssss" };
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)

In reply to Regex result being defined when it shouldn't be(?) by chenhonkhonk

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.