http://qs321.pair.com?node_id=637075

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

Hi all,

%rules = ( INPUT_FILE_DESCRIPTION => "^Remote.*" );
Above is the standard hash that we are using in our projects. There is a base module written to process this standard hash. Functionality is, If it sees the key INPUT_FILE_DESCRIPTION then base module does process only the files which start with "Remote". Now I want to process all the files which does not start with "Remote".

what is the regular expression I can apply there in INPUT_FILE_DESCRIPTION. Because We do not want to disturb the base module which are being used. At worst case if we have no idea of doing in INPUT_FILE_DESCRIPTION then we have to introduce a new key as FILE_NAME_DOES_NOT_START_WITH and we need to write a code in base module to process this new key as well.

Apologies If I have confused you all more with my problem description.



i m possible

Replies are listed 'Best First'.
Re: Regular expression question strikes again
by Corion (Patriarch) on Sep 05, 2007 at 07:21 UTC

    Some more code would help. Currently I imagine your base module and main program to be something like this:

    #!/usr/bin/perl -w use strict; use vars qw(%rules); # From the base package sub filter_names { my ($rule_name,@files) = @_; my $rule = $main::rules{ $rule_name }; grep {/$rule/} @files }; %rules = ( INPUT_FILE_DESCRIPTION => "^Remote.*", OTHER_FILES => "^(?!Remote)" ); my @files = <DATA>; chomp @files; for my $rule (qw(INPUT_FILE_DESCRIPTION OTHER_FILES)) { print "$rule\n"; print "$_\n" for filter_names($rule, @files); }; __DATA__ Remote1 Other1 Remote2 Other2 Remote3 Another

    My solution uses the negative lookahead, anchored to the start of the string. See perlre to find out more about negative lookahead. Also, you might want to consider a different approach that remembers whether a file was handled by a rule already and then raising an error about all unhandled files. Doing that would be possible by remembering for each file the rule(s) that applied.

Re: Regular expression question strikes again
by sgt (Deacon) on Sep 05, 2007 at 09:47 UTC

    probably you just need Corion's solution, but be careful when you mix positive and negative logic. Imagine you have qr{^Remote.*$} and qr{^.*tmp$} You might want to process all Remote files that don't end in tmp.

    Maybe it's better to have a two-pass (or n-pass) filter, with a first pass using positive logic and a second pass using negative logic, for instance. The point is that you use the same rules in any pass.

    So you use positive logic labels, and your filter decides if it wants to grep or 'grep { not ...}'

    cheers --stephan
Re: Regular expression question strikes again
by Anonymous Monk on Sep 05, 2007 at 10:03 UTC
    there is also the !~ no-match binding operator.

    ``Binary "!~" is just like "=~" except the return value is negated in the logical sense.''

    see Binding Operators in perlop.

      there is also the !~ no-match binding operator.

      As a side note there's been a very interesting discussion about negating regexen.

        nice discussion. I missed it somehow.

        I wonder if the regex engine could give it. A negated compiled form seems possible. Then there would be the problem of giving a regex that corresponds to a given compiled form. Still a special flag could be used to say "already compiled" and somehow could make it useful as part of a bigger regex (not fully compiled).

        This seems to ring some bells of a discussion on p5p about the actual scheme of adding qr// parts.

        cheers --stephan the rewrite feeling is strong today;)
Re: Regular expression question strikes again
by oha (Friar) on Sep 05, 2007 at 09:25 UTC
    for what i understood, you are going not to make some regexp test around, but there is more logic within.

    have you ever considered Parse::RecDescent? you can use regexp for matching, and it's grammar for your logic.

    Oha