2011-12-30 27 views
5

Tôi có một chức năng để tìm kiếm một chuỗi trong một danh sách liệt kê sau đó trả về một danh sách có chứa danh sách phù hợp:Python chuỗi tiên tiến tìm kiếm với các nhà khai thác và boolean

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

Bây giờ tôi muốn mở rộng nó để xử lý tìm kiếm nâng cao với các truy vấn như:

matchthis -butnothis -"and not this" 

this|orthis|"or this" 

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

"exact phrase" 

Có bất kỳ mô-đun trăn (tốt nhất là nội trang) mà tôi có thể sử dụng trong chức năng để xử lý các truy vấn này không?

PS: Tôi biết Swoosh nhưng nó không phù hợp với tôi vào lúc này. Ngoài ra, tôi hiện đang sử dụng App Engine.

Điều tôi đang cố gắng thực hiện cơ bản là tìm kiếm toàn văn bản trong bộ nhớ, vì công cụ ứng dụng không hỗ trợ tìm kiếm toàn văn. Tôi truy vấn kho dữ liệu, đưa các thực thể vào danh sách và lặp qua các danh sách đó để tìm các kết quả truy vấn.

Trả lời

4

Tôi sẽ thử xây dựng một regex cho từng phần của truy vấn tìm kiếm. Trước tiên, bạn có thể chia truy vấn thành các phần bằng cách sử dụng shlex.split() và sau đó tạo từng regex riêng lẻ. Đây là vết nứt của tôi lúc đó:

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 

này sẽ trả về một chức năng mà bạn có thể sử dụng để xác nhận đối với các truy vấn, ví dụ:

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

Bạn sẽ có thể thêm vào một số xử lý bằng ký tự đại diện thay thế * trong truy vấn bằng .* trong regex.

+0

trông rất hứa hẹn, hãy để tôi thử. – ofko

+0

đây là sự hoàn hảo! Cảm ơn bạn. – ofko

2

Không có mô-đun thư viện chuẩn nào thực hiện tất cả những gì bạn muốn; Tuy nhiên, bạn có thể bắt đầu với shlex module để phân tích các nhóm tìm kiếm:

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

Bạn cũng có thể ghé qua re module trong trường hợp bạn cần kiểm soát hạt mịn hơn trong phân tích cú pháp.

+0

Tôi đã nghĩ về việc sử dụng regex nhưng tôi cảm thấy rằng nó sẽ rất chậm cho một danh sách dài khoảng 1000 với mỗi văn bản là một hoặc hai đoạn văn. – ofko

+0

Nếu bạn biên dịch trước các regex, chúng có thể rất nhanh và khó đánh bại với bất kỳ kỹ thuật python thuần túy nào khác. –

Các vấn đề liên quan