Re: in the elemetns of programming perl , I need help with 2 lines that I don't understand
[email protected] (Rob Dixon)
| Newsgroups | perl.beginners |
|---|---|
| Message-ID | <[email protected]> |
Richard Lee wrote:
> In the book "elements of programming perl", below program is presented.
>
> I don't really understand these 2 lines. can someone break it down for
> me please?
>
> $pattern = '.*(?:' . join('|', @ARGV) . ')';
>
> $pattern = join('', map{"(?=.*$_)"} @ARGV);
>
>
> #!/usr/bin/perl
>
>
> use strict;
> use warnings;
>
> my $faqdir = '/usr/lib/perl5/5.10.0/pod/';
> my($opt_f,$opt_or,$pattern);
>
> die "no keywords specified\n" unless @ARGV;
>
> while ( $ARGV[0] =~ /^-/ ) {
> $_ = $ARGV[0];
> if ( /^-or$/ ) { $opt_or = 1; shift @ARGV; next }
> if ( /^-f$/ ) { $opt_f = 1; shift @ARGV; next }
> die<<HERE;
> illegal option: $_
> usage: faqgrep [-f] [-or] [keywords...]
> HERE
> }
>
> if ( $opt_or) {
> $pattern = '.*(?:' . join('|', @ARGV) . ')';
> } else {
> $pattern = join('', map{"(?=.*$_)"} @ARGV);
> }
> opendir(FAQDIR,$faqdir) or die "can't open $faqdir $!";
> my @faqs = grep /faq/, readdir FAQDIR;
> closedir FAQDIR;
>
> foreach my $faq ( @faqs ) {
> open ( FAQ, "$faqdir/$faq" ) or die "can't $!";
> while ( <FAQ> ) {
> if (s/^=head2($pattern)/$1/io) {
> print "$faq:$_";
> if ( $opt_f ) {
> while ( <FAQ> ) {
> last if m/^=head(?!$pattern)/io;
> print;
> }
> }
> }
> }
> }
It's always confusing when a program written in one language (here, Perl)
creates a program in another (this script is building regular expressions).
Look at the strings those lines are generating.
use strict;
use warnings;
local @ARGV = qw/A B C/;
my $or_pattern = '.*(?:' . join('|', @ARGV) . ')';
my $and_pattern = join('', map{"(?=.*$_)"} @ARGV);
print "Or pattern: $or_pattern\n";
print "And pattern: $and_pattern\n";
**OUTPUT**
Or pattern: .*(?:A|B|C)
And pattern: (?=.*A)(?=.*B)(?=.*C)
Now can you understand those as regular expressions? The former uses
non-capturing parentheses (?: ... ) to find any one of the values anywhere in
the string, while the latter uses a lookahead (?= ... ) to find a point in the
string after which all three of the values appear anywhere.
HTH,
Rob