[Date Prev][Date Next][Thread Prev][Thread Next] [Search] [Date Index] [Thread Index]

Re: [MacPerl] Grep based on user input?



At 11:24 PM 12/19/00, Matthew Fischer wrote:
>How can you dynamically build a grep pattern based on user input from a form?
>
>i.e.: (I know this doesn't work):
>
>   if ($input{'month'} ne "") {
>       @allfiles = grep(/$input{'month'}/,@allfiles);
>       }

Perl's grep takes a list as input, and returns a list as output. The 
returned list is each element of the input list for which some 
specified operation returns true.

The block form of grep is more revealing:

@output_list = grep { #truth_test# } @input_list;

Each element of @input_list is submitted in order to the truth test; 
the value of the input element is placed in the 'it' variable $_ 
inside the block.

@test1 = grep { $_ =~ /[0-9]/ } ('one', 'two', 3, 'four', 5, 6 );

@test1 gets the elements: 3, 5, 6.

Because of the magic of the it variable, the truth test $_ =~ /[0-9]/ 
may be shortened:

@test1 = grep { /[0-9]/ } ('one', 'two', 3, 'four', 5, 6 );

or finally, the 'short' form of grep:

@test1 = grep /[0-9]/, ('one', 'two', 3, 'four', 5, 6 );

Whtever the form, the important thing is that the truth test is done 
for each element of the input list. It's not even necessary to _use_ 
the $_ value in the truth test, but if the truth test returns true, 
then that element is added to @output_list.

@test2 = grep { 1 == 1 } ('one', 'two', 3, 'four', 5, 6 );

@test2 gets _all_ of the input elements because the expression in the 
block will return true for every element of the input list. Of 
course, usually one does test the input elements...

The truth test may be as complex a block as you need, multi-lined, 
with all manner of variables, comparisons, subroutine calls, etc:

@out_list = grep {
   my @args = split ':', $_;  # $_ is each successive element of @in_list
   if ($arg[0] ne ''
     and $arg[1] =~ /^\s*[0-9]{2,5}\s*$/) {
       test($arg[3])
     } else {
       $arg[4] == $arg[5]
     }
} @in_list;

Does any of this help?

It's not clear from your example what you'd been hoping that 
expression might do, but as it's written what it does is test each 
successive element of @allfiles to see if it matches the value in 
$input{'month'}; if so, that element goes into the output list (also 
@allfiles).

1;


- Bruce

__Bruce_Van_Allen___Santa_Cruz_CA__

# ===== Want to unsubscribe from this list?
# ===== Send mail with body "unsubscribe" to macperl-request@macperl.org