2012-12-25 74 views
6

Khi tôi cố gắng sử dụng cụm từ thông dụng để tìm chuỗi trong các chuỗi khác, nó không hoạt động như mong đợi. Dưới đây là một ví dụ:Tìm kiếm các chuỗi bằng cách sử dụng cụm từ thông dụng trong Python

import re 
message = 'I really like beer, but my favourite beer is German beer.' 
keywords = ['beer', 'german beer', 'german'] 

regex = re.compile("|".join(keywords)) 
regex.findall(message.lower()) 

Kết quả:

['beer', 'beer', 'german beer'] 

Nhưng kết quả dự kiến ​​sẽ là:

['beer', 'beer', 'german beer', 'german'] 

Một cách khác để làm điều đó có thể là:

results = [] 
for k in keywords: 
    regex = re.compile(k) 
    for r in regex.findall(message.lower()): 
     results.append(r) 

['beer', 'beer', 'beer', 'german beer', 'german'] 

Nó hoạt động như tôi muốn, nhưng tôi nghĩ nó là n ot cách tốt nhất để làm điều đó. Ai đó có thể giúp tôi được không?

Trả lời

6

re.findall không thể tìm thấy kết quả trùng lặp trùng lặp. Nếu bạn muốn sử dụng các biểu thức chính quy, bạn sẽ phải tạo các biểu thức riêng biệt và chạy chúng trong một vòng lặp như trong ví dụ thứ hai của bạn.

Lưu ý rằng ví dụ thứ hai của bạn cũng có thể được rút ngắn xuống còn sau đây, mặc dù đó là một vấn đề của hương vị cho dù bạn tìm thấy điều này dễ đọc hơn:

results = [r for k in keywords for r in re.findall(k, message.lower())] 

ví dụ cụ thể của bạn không đòi hỏi việc sử dụng các biểu thức thông thường. Bạn nên tránh sử dụng cụm từ thông dụng nếu bạn chỉ muốn tìm các chuỗi cố định.

+0

Các người hỏi không chỉ muốn kiểm tra xem một chuỗi đặc biệt là một phần của một chuỗi nhưng ông muốn tất cả các lần xuất hiện của một chuỗi cụ thể. Trong trường hợp này, việc sử dụng 're.findall()' là cách tốt nhất để thực hiện điều đó. Tránh các biểu thức chính quy sẽ làm cho giải pháp này mất thời gian hơn mức cần thiết. – pemistahl

+0

Cảm ơn các bạn đã trả lời. Bây giờ tôi biết tôi đang sử dụng một chức năng sai (findall), vì vậy những gì bạn đề nghị để tìm các trận đấu, bao gồm cả overlappings? –

+0

@ Adrián: Bạn có cần sức mạnh của cụm từ thông dụng hay bạn chỉ muốn tìm các chuỗi cố định? –

6

re.findall được mô tả trong http://docs.python.org/2/library/re.html

"Return tất cả các trận đấu không chồng chéo của mẫu trong chuỗi ..."

không chồng chéo có nghĩa là cho "bia Đức" nó sẽ không tìm thấy "bia Đức" VÀ "đức", bởi vì những trận đấu đó trùng nhau.

+0

Cảm ơn bạn đã trả lời Omri Barel. Bạn đề xuất gì để tìm các kết quả phù hợp, bao gồm cả chồng chéo? –

+0

Nói chung, bạn phải làm những gì bạn đã làm: một từ khóa tại một thời điểm. Nhưng đối với một giải pháp tốt hơn, bạn sẽ phải mô tả những gì bạn đang thực sự cố gắng làm (tức là tình hình thực tế mà không đơn giản hóa các ví dụ tầm thường) là gì. –

+0

Omri, như tôi đã viết trong câu trả lời dưới đây, tôi hỏi về biểu thức thông thường bởi vì tôi đã nghĩ rằng đó là cách tốt nhất và tối ưu để làm điều đó. Các chuỗi fo tìm thấy sẽ luôn luôn cố định (word1 | word2 | word3 ...), tôi có nghĩa là không có regex phức tạp. –

1

sạch của tôi (cho tôi) phiên bản dành cho giải pháp cuối cùng của bạn

results = [] 
for key in keywords: 
    results.extend(re.findall(key, message, re.IGNORECASE)) 
Các vấn đề liên quan