2012-04-23 84 views
0

查询条件应该支持布尔运算符和正则表达式。我已阅读过Booleano,但它不支持正则表达式。在Python中,如何查询单词列表以匹配某个查询条件?

如果没有符合这个要求的东西,那将是开始建立的最佳技术?

以下示例中的语法只是一个示例,但它提供的功能应该存在。

is True if ('client/.+' and 'user_a') but (not 'limited' unless ('.+special' or 'godmode')) 

它等于施加在下面列出

is_true = ['client/chat', 'user_a', 'limited', 'extraspecial'] 
is_false = ['client/ping', 'user_a', 'limited'] 
is_false = ['server/chat'] 
is_false = ['server/ping', 'ping'] 
+0

在这种情况下,我认为使用整数 - 按位运算符,甚至 - 会是更好的选择。如果你对这样做感到满意,你可以用[此链接](http://stackoverflow.com/a/1695250/1079354)中的示例制作一种枚举对象。 – Makoto 2012-04-23 14:01:37

+0

我不明白这可以用于正则表达式查询。 'client /.+'本身就是一个查询。 – 2012-04-23 14:12:23

+0

PyBoolRe非常接近我需要的,但它在复杂的嵌套上失败。我希望我可以使用mongodb语法及其引擎对进程内列表执行此类查询,而不需要将列表放入数据库并通过套接字查询。 – 2012-04-23 15:05:44

回答

1

我管理与使用pyparsing模块的要解决的问题

is True if 'client/.+' and 'user_a' and (not ('limited' and (not ('.+special' or 'godmode')))) 

import re 
import pyparsing 

class BoolRegEx(object): 

    def Match(self, tags=[], query=""): 
    self.tags = tags 
    if ' ' not in query: 
     return self.Search(query) 
    else: 
     return pyparsing.operatorPrecedence(
     pyparsing.Word(pyparsing.printables, excludeChars="()"), [ 
      (pyparsing.Literal("NOT"), 1, pyparsing.opAssoc.RIGHT, self.Not), 
      (pyparsing.Literal("OR"), 2, pyparsing.opAssoc.LEFT, self.Or), 
      (pyparsing.Literal("AND"), 2, pyparsing.opAssoc.LEFT, self.And), 
     ] 
    ).parseString(query, parseAll=True)[0] 

    def Search(self, a): 
    try: 
     regex = re.compile(a.replace("<<", "#~").replace(">>", "~#").replace(">", ")").replace("<", "(").replace("#~", "<").replace("~#", ">")) 
     for tag in self.tags: 
     match = regex.match(tag) 
     if match and len(match.group(0)) == len(tag): 
      return True 
     return False 
    except: 
     raise 

    def And(self, t): 
    for a in t[0][0::2]: 
     if isinstance(a, basestring): 
     v = self.Search(a) 
     else: 
     v = bool(a) 
     if not v: 
     return False 
    return True 

    def Or(self, t): 
    for a in t[0][0::2]: 
     if isinstance(a, basestring): 
     v = self.Search(a) 
     else: 
     v = bool(a) 
     if v: 
     return True 
    return False 

    def Not(self, t): 
    a = t[0][1] 
    if isinstance(a, basestring): 
     return not self.Search(a) 
    else: 
     return not bool(a) 

print BoolRegEx().Match(['client/chat', 'user_a', 'limited', 'extraspecial'], "client/.+ AND user_a AND NOT (limited AND NOT (.+<r|i>special OR godmode))") 
# False 

print BoolRegEx().Match(['client/chat', 'user_a', 'limited', 'superspecial'], "client/.+ AND user_a AND NOT (limited AND NOT (.+<r|i>special OR godmode))") 
# True 

我不得不更换与<正则表达式()>,以避免碰撞,但在这一刻这一切似乎是最好的解决办法。

+0

我希望在C代码中有这个功能 – 2014-09-22 19:17:15