2011-12-30 22 views
5

搜索我有在名單列表中搜索字符串的函數,然後返回一個包含匹配列表清單:Python的高級字符串與運營商和布爾

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:我知道旋風,但它不是正確的適合我的那一刻。另外,我目前正在使用App Engine。

我想要做的基本上是在內存中進行全文搜索,因爲應用引擎不支持全文搜索。我查詢數據存儲,將這些實體放入列表中並遍歷這些列表以查找查詢匹配。

回答

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 

你應該能夠在一些通配符處理添加用正則表達式中的.*代替查詢中的*

+0

這看起來很有前途,讓我試試看吧。 – ofko 2011-12-30 02:07:18

+0

這是完美!謝謝。 – ofko 2011-12-30 03:20:36

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你需要在解析更爲精細的控制。

+0

我想過使用正則表達式,但我的印象是,對於列表長度大約爲1000的列表來說,每個文本都是段落或兩個列表會很慢。 – ofko 2011-12-30 01:47:14

+0

如果你預編譯正則表達式,它們可以非常快,很難用任何其他純Python技術擊敗。 – 2011-12-30 01:51:50