Bravo! :)
Another approach: assuming, that we can "upgrade" filter a little
$_=<<END_OF_FILTER; (AND (OR (AND (COND AUTHOR=John) (COND PROFIT=90%) ) (AND (COND AUTHOR=Matt) (COND PROFIT=80%) ) ) (COND PUBLISHER=OReilly) ) END_OF_FILTER %hash = ( AUTHOR=> 'John', PROFIT=> '90%', PUBLISHER=> 'OReilly', BOOK=> 'OPERATING SYSTEMS' ); sub AND { print "and debug: [@_]"; for(@_) { return 0 if ! $_ } return 1 } sub OR { print "or debug: [@_]"; for(@_) { return 1 if $_ } return 0 } sub COND { my ($key, $value)=@_; $ret = 0 | ($hash{$key} eq $value); print "cond debug: @_ -> $ret"; return $ret } # add comas between ) and ( braces s/\)(\s*)\(/),$1(/g; # convert COND a little - I hope you do not have O'reilly name... :) s/\(COND (\w+)=([^)]+)\)/(COND '$1','$2')/g; # we have proper parens already, move it only s/\((AND|OR|COND)\b/$1(/g; # see how it looks now print $_; # and voila! print "ok" if eval;
Update: The question is only how to add (COND ...) block with one regexp to original filter? Search for '=' like this?
s/\w+=\S+/(COND $&)/g
Or there can be whitespace in some values, on which regexp fails? As only legend knows the format of conditions, the answer and a good regexp is in the legend :)
In reply to Re^2: Implementing a text filter on some dataset
by grizzley
in thread Implementing a text filter on some dataset
by legend
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |