0

クエリ条件は、ブール演算子と正規表現をサポートする必要があります。Booleano について読んだことがありますが、正規表現をサポートしていません。

この要件に一致するものがない場合、構築を開始するのに最適なテクノロジはどれですか?

以下の例の文法は単なる例ですが、それが提供する機能は存在するはずです。

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

に等しい

is True if 'client/.+' and 'user_a' and (not ('limited' and (not ('.+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']
4

1 に答える 1

1

pyparsing モジュールを使用して問題を解決できました。

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

衝突を避けるために regexp () を <> に置き換える必要がありましたが、現時点ではこれが最善の解決策のようです。

于 2012-04-25T22:16:03.260 に答える