Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic

Reverse grep?

by JamesA (Acolyte)
on Mar 01, 2002 at 18:41 UTC ( #148645=perlquestion: print w/replies, xml ) Need Help??

JamesA has asked for the wisdom of the Perl Monks concerning the following question:

I am writing a perl CGI to trap hack attempts on my web server. Right now I am implementing this with "ScriptAliasMatch" commands in httpd.conf but this method is getting unwieldy as the number of patterns are increasing.

I would like an error document CGI to run a loop reading regexes from a file and compare them to the requested URL until a match is found or all the regexes have been tested.

I have not found any samples yet that point me in the right direction to perform this 'reverse grep' type of function.

Replies are listed 'Best First'.
Re: Reverse grep?
by chromatic (Archbishop) on Mar 01, 2002 at 19:18 UTC
Re: Reverse grep?
by rbc (Curate) on Mar 01, 2002 at 19:09 UTC
    If you mean grep -v behavoir you could try ...
    my @results = grep { !/$pattern/ }, @array;
    ... I hope that works. If not let me know cause
    I use it in some of my scripts.
Re: Reverse grep?
by Juerd (Abbot) on Mar 01, 2002 at 19:39 UTC
    For information about Perl's grep command, use perldoc -f grep.

    To reverse the condition, negate the condition: grep { !( expression ) } LIST (Using a block is easier in many cases, and read perlop to find out when you can leave out the parens).
    To reverse grep's output, use reverse: reverse grep BLOCK LIST or reverse grep EXPR, LIST

    Lbh ebgngrq guvf grkg naq abj lbh pna ernq vg. Fb jung? :) -- Whreq

Re: Reverse grep?
by chipmunk (Parson) on Mar 02, 2002 at 17:23 UTC
    By "reverse grep", I take it that you mean you want to loop over a list of regexes with one string, rather than loop over a list of strings with one regex. As far as Perl is concerned, these are the same.

    Your difficulty comes from thinking of Perl's grep as being the same as the command line grep. This is not the case. In Perl's grep, the conditional is not necessarily a pattern match; it is any arbitrary Perl expression. For example, you could do something like this: @results = grep { $_ & 1 } (1 .. 10) to get a list of odd numbers between 1 and 10.

    Thus, you can do any filtering you want with grep, with the proper conditional expression. What you're looking for could be written something like this (with some regexes I made up):

    my $url = ''; my @regexes = ('/private(?:/|$)', 'python'); if (grep { $url =~ $_ } @regexes) { # handle bad URL } else { # handle good URL }
    As suggested in another response, you'd probably want to precompile the regexes with qr// for efficiency.
Re: Reverse grep?
by JamesA (Acolyte) on Mar 02, 2002 at 00:45 UTC
    I am trying to do something like the following but can't get it to work:
    open FILE, "regex" or die "Couldn't open: $!"; while (<FILE>) { if ( $ENV{"REDIRECT_URL"} +~ /$_/ ) { print $_; last; } } close FILE;

    Where the file "regex" would contain all of the patterns I want to test against the URL.

      You need to add this:
      while (<FILE>) { + chomp; if ( $ENV{"REDIRECT_URL"} +~ /$_/ ) { print $_; last; }
      Otherwise, you have a trailing newline at the end of your pattern.

      I think +~ might be a typo. Don't you want this instead?
      if ( $ENV{"REDIRECT_URL"} =~ /$_/ ) { print $_; last; } ^

      Please correct me if I'm wrong.

        Considering that one must hold down the shift key for the tilde character, coupled with the fact that the plus sign character shares the same key as the equal sign character ... yes ;)

        But, have you played with the results yet?

        [prompt]$ perl -le 'print /RED/' [prompt]$ perl -le 'print ~/RED/' 4294967295 [prompt]$ perl -le 'print hex("F"x8)' 4294967295 [prompt]$ perl -le '$_ = "REDIRECT"; print /RED/' 1 [prompt]$ perl -le '$_ = "REDIRECT"; print ~/RED/' 4294967294 [prompt]$ perl -le '$_ = "REDIRECT"; print 5+~/RED/' 4294967299
        Gotta love Perl's flexibility! :D


        (the triplet paradiddle with high-hat)

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://148645]
Approved by root
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others examining the Monastery: (2)
As of 2021-12-05 20:38 GMT
Find Nodes?
    Voting Booth?
    R or B?

    Results (31 votes). Check out past polls.