Showing posts with label perl. Show all posts
Showing posts with label perl. Show all posts

Friday, July 01, 2011

Alternation without Capture/Extraction/Selection

This drove me crazy for longer than I wanted (since I would want that for varying amounts of time) so I will note it here for other frustrated people to find.

I had a regular expression from which I wanted to capture part of it in $1. I also had an alternation in it that needed grouping with parentheses. It kept capturing the alteration in $1 when I didn't care or want to capture that at all.

This is an example of what I had at first that didn't do what I wanted:

$string =~ /bytes\s+=\s+\d+\.?\d*(K|M)?\s+\(\s*(\d+\.?\d*)\%/;

The above code was giving me either 'K' or 'M' in $1 if either were there instead of what I wanted which was the second grouping (\d+\.?\d*). I just needed to know how to stop the capture since stuff like K|M? and K?|M? without parentheses didn't work right either.

After a lot of online searching using probably the wrong query terms, I found the concept of "non-capturing groupings" which are apparently denoted by (?:regex).

Changed my code to this to finally get what I wanted:

$string =~ /bytes\s+=\s+\d+\.?\d*(?:K|M)?\s+\(\s*(\d+\.?\d*)\%/;

This way the 'K' or 'M' isn't captured and I get the second grouping (\d+\.?\d*) stored in $1.

Friday, May 20, 2011

Storing Options with Multiple Values in a Hash using Getopt::Long

I'm relatively new to Perl and was writing a program that takes long options on the command line. I quickly found the Getopt::Long module and started out getting options where each option's value was stored in a separate variable. One of the options has multiple values, e.g. --option5 0 1 2.

When I started, I had something like:

my ($option1, $option2, $option3, $option4, @option5);
my $result = GetOptions('option1=s'    => \$option1,
                        'option2=i'    => \$option2,
                        'option3=s'    => \$option3,
                        'option4=s'    => \$option4,
                        'option5=i{,}' => \@option5);

I wanted to change it to store the options in a hash since I had several options but got confused with the option that takes multiple values using a repeat specifier. The reason was stated in the documentation that "The destination for the option must be an array or array reference." What I didn't realize is that I needed to use this syntax "Alternatively, you can specify that the option can have multiple values by adding a "@", and pass a scalar reference as the destination" since my destination was now an uninitialized hash entry.

I ended up with this:

my %options;
my $result = GetOptions(\%options, 'option1=s',
                                   'option2=i',
                                   'option3=s',
                                   'option4=s',
                                   'option5=i@{,}');