Python使用运算符和布尔值进行高级字符串搜索

时间:2011-12-30 01:19:33

标签: python google-app-engine

我有一个函数可以搜索列表列表中的字符串,然后返回一个包含匹配列表的列表:

def foo(myList,keyword,first=True):
    if first: #Search only first element or each sublist
        return [x for x in myList if keyword in x]
    else: #Search first and second elements of each sublist
        return [x for x in myList if keyword in x or keyword in x[1]]

现在我想扩展它以处理高级搜索,例如:

matchthis -butnothis -"and not this"

this|orthis|"or this"

brand new*laptop  # this is a wildcard, matches like: brand new dell laptop

"exact phrase"

我可以在我的函数中使用任何python模块(最好是内置的)来处理这些查询吗?

PS:我知道Swoosh,但目前它不适合我。另外,我目前正在使用App Engine。

我正在尝试做的基本上是内存中的全文搜索,因为app引擎还不支持全文搜索。我查询数据存储区,将实体放入列表并循环遍历这些列表以查找查询匹配。

2 个答案:

答案 0 :(得分:4)

我会尝试为搜索查询的每个部分构建一个正则表达式。首先,您可以使用shlex.split()将查询分解为部分,然后单独创建每个正则表达式。以下是我的解答:

import shlex, re

def foo(query):
    pieces = shlex.split(query)
    include, exclude = [], []
    for piece in pieces:
        if piece.startswith('-'):
            exclude.append(re.compile(piece[1:]))
        else:
            include.append(re.compile(piece))
    def validator(s):
        return (all(r.search(s) for r in include) and
                not any(r.search(s) for r in exclude))
    return validator

这将返回一个可用于验证查询的函数,例如:

>>> test = foo('matchthis -butnothis -"and not this"')
>>> test("we should matchthis...")
True
>>> test("some stuff matchthis blah and not this...")
False

您应该可以通过在查询中将*替换为正则表达式中的.*来添加一些通配符处理。

答案 1 :(得分:2)

没有一个标准库模块可以完成你想要的所有工作;但是,您可以从 shlex module 开始解析搜索组:

>>> import shlex
>>> s = '''matchthis -butnothis -"and not this"
this|orthis|"or this"
brand new*laptop
"exact phrase"
'''
>>> shlex.split(s)
['matchthis', '-butnothis', '-and not this', 'this|orthis|or this', 'brand', 'new*laptop', 'exact phrase']

如果您需要对解析进行更精细的控制,您还可以查看 re module