Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change

Re^2: AND and OR on Regular Expressions

by vitoco (Friar)
on Aug 25, 2009 at 21:18 UTC ( #791174=note: print w/replies, xml ) Need Help??

in reply to Re: AND and OR on Regular Expressions
in thread AND and OR on Regular Expressions

Added another improvement to this converter: "word not in keywords" feature. This is becoming interesting!

This is an updated code that tries many queries with a simple expression validation included:

#!perl -w my @data = <DATA>; for my $test ( # ( "olive&(popeye|bluto)", "(tom&jerry)|(sylvester&tweety)", "moe&(shemp|curly|joe)&larry", "moe curly larry", # "&" is optional "moe&!curly&larry", # curly not present "moe ( shemp | curly | joe ) larry", # "|" is required "jerry -tom", # standard way of "AND" and "AND NOT"... "(moe)((shemp)|(curly)|(joe))(larry)", # also this "tom&jerry|sylvester&tweety", # use re's default precedence "moe(&shemp|curly|joe)&larry", # error: "(&" instead of "&(" "moe ( shemp | curly | joe", # error: missing ")" "moe ) curly ( larry", # invalid: bad grouping "(olive)&(popeye|(bluto|brutus)))", # error: extra ")" "(jerry)((tweety))( )", # error: empty group "jerry||tweety", # error: empty word "olive - (bluto | brutus)", # only words can be excluded "olive - bluto - brutus", # Ok, spaces ignored. "(curly|!larry)&!moe", # valid, but senseless OR "moe&!(!curly)&larry", # error: curly present? "tom -!jerry" # error: don't try... # )[(shift)-1] ) { print "\n\n$test\n::\n"; (print("ERROR: Invalid expression\n") , next) if $test =~ /[^a-z\s\&\|\(\)\!\-]|^\s*[\&\|]|[\&\|]\s*$|[\&\|\(]\s +*[\&\|\)]|[\!\-]\s*[^a-z\s]/; # not_valid_chars |op_begins | op_ends | no_consec +utive_ops| negated_operator my $pars = $test; my $i = 0; $i++ while $pars =~ s/\((.*?)\)/$1/; (print("ERROR: Unpaired $1 of other $i pairs found\n") , next) if $pars =~ /([\(\)])/; my $expr = $test; $expr =~ s/([!\-]?)\s*(\w+)/($1?"(?!":"(?=").".*\\b$2\\b)"/ge; $expr =~ s/[\&\s]//g; $expr = "^($expr)"; print "$expr\n::\n"; print grep /$expr/, @data; } __DATA__ tom,jerry jerry,tom jerry,tomas sylvester,tweety tweeter,sylvester tom,sylvester popeye,olive olive,brutus moe,larry shemp,curly,joe larry,moe larry,curly,moe

To try just one of the queries, remove the comment's chars from the for at the begining, and give a number (starting from 1) as an argument in the command line.

I also removed the captures while building the regexp because them aren't used. I've just put them there for clarification.

The validation code is simple because the allowed syntax is simple too, and is very tied to regular expressions.

BTW, is there a better way to write the lines to check for parity of parentheses?

Replies are listed 'Best First'.
Re^3: AND and OR on Regular Expressions
by grizzley (Chaplain) on Aug 26, 2009 at 07:19 UTC

    I would rather use:

    $i++ while $pars =~ s/\(([^()]*)\)/$1/;

    Better way is to use Regexp::Common and balanced pattern (not tested):

    use Regexp::Common; $pars =~ /^[^()]*$RE{balanced}{-parens=>'()'}[^()]*$/

      The first regexp I thought for the while was the same as yours, which is syntactically correct, since it removes the matching parenteses, starting from the inner ones when nested. But used the other regexp because I think it's faster, and nothing will be done with the remaining string other than to look if there is at least one of the parentheses remaining.

      Using the balanced option of that module sound interesting, but, again, I think that my problem was easy enougth to try an external pattern that calls another subroutine, which is able to manage multiple delimiters.

      I'm still viewing the available regexp modules' docs in CPAN, looking for one that does all I did here at the same time.

      Anyway, thank you for the hints!!!

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://791174]
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others browsing the Monastery: (2)
As of 2017-05-23 01:54 GMT
Find Nodes?
    Voting Booth?