在 Python 中,如何查询单词列表以匹配某个查询条件? [英] In Python, how can I query a list of words to match a certain query criteria?

查看:47
本文介绍了在 Python 中,如何查询单词列表以匹配某个查询条件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

查询条件应支持布尔运算符和正则表达式.我读过有关 Booleano 的文章,但它不支持正则表达式.

The query criteria should support boolean operators and regular expressions. I've read about Booleano, but it doesn't support regular expressions.

如果没有任何符合此要求的技术,那么开始构建的最佳技术是什么?

If there is nothing out there which matches this requirements, which would be the best technology to start building upon?

下面例子中的语法只是一个例子,但它提供的功能应该存在.

The grammar in the example below is just an example, but the feature it offers should exist.

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']

推荐答案

我通过使用 pyparsing 模块设法解决了这个问题.

I managed to solve the problem with the use of the pyparsing module.

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() 替换为 <>,但目前所有这些似乎都是最好的解决方案.

I had to replace the regexp () with <> in order to avoid collisions, but at this moment all of this seems to be the best solution.

这篇关于在 Python 中,如何查询单词列表以匹配某个查询条件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆