2011-12-30 10 views
5

Mam funkcja, która przeszukuje ciąg na liście list następnie zwraca listę zawierającą list Dopasowanie:Python zaawansowany ciąg poszukiwania z operatorami i logiczną

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

Teraz chcę przedłużyć go obsłużyć Zaawansowane wyszukiwanie z zapytaniami takimi jak:

matchthis -butnothis -"and not this" 

this|orthis|"or this" 

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

"exact phrase" 

Czy są jakieś moduły Pythona (najlepiej wbudowane), których mogę użyć w mojej funkcji do obsługi tych zapytań?

PS: Jestem świadomy Swoosh, ale w tej chwili nie pasuje mi to. Ponadto używam App Engine.

Co staram się zasadniczo zrobić, to wyszukiwanie pełnotekstowe w pamięci, ponieważ aparat aplikacji nie obsługuje jeszcze wyszukiwania pełnotekstowego. Pytam datastore, umieszczam podmioty na listach i przechodzę przez te listy, aby znaleźć dopasowania zapytań.

Odpowiedz

4

Chciałbym spróbować skonstruować wyrażenie regularne dla każdej części zapytania. Najpierw możesz podzielić zapytanie na porcje, używając shlex.split(), a następnie utworzyć osobno każde wyrażenie regularne. Oto moja pęknięcie na to:

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 

ten powróci do funkcji, które można wykorzystać do sprawdzania poprawności przeciwko zapytania, na przykład:

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

Powinieneś móc dodać w pewnym obsługi przez wildcard zastępując * w zapytaniu z .* w regex.

+0

to wygląda bardzo obiecująco, pozwól mi spróbować. – ofko

+0

to jest perfekcja! Dziękuję Ci. – ofko

2

Nie ma jednego standardowego modułu bibliotecznego, który robi wszystko, co chcesz; Można jednak zacząć od shlex module do analizowania grup kryteriów:

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

Można też zajrzeć na re module w przypadku trzeba bardziej drobnoziarnista kontrolę nad parsowania.

+0

Myślałem o używaniu regex, ale mam wrażenie, że będzie bardzo powolny dla listy o długości około 1000 z każdym tekstem będącym akapitem lub dwoma. – ofko

+0

Jeśli prekompilujesz wyrażenia regularne, mogą one być bardzo szybkie i trudne do pokonania przy użyciu dowolnej czystej techniki Pythona. –

Powiązane problemy