2011-02-10 35 views
10

Tôi đã có danh sách các mẫu chính xác mà tôi muốn tìm kiếm trong một chuỗi nhất định. Hiện tại tôi đã có một giải pháp thực sự tồi tệ cho một vấn đề như vậy.Cách đối sánh chính xác các chuỗi "nhiều" trong Python

pat1 = re.compile('foo.tralingString') 
mat1 = pat1.match(mystring) 

pat2 = re.compile('bar.trailingString') 
mat2 = pat2.match(mystring) 

if mat1 or mat2: 
    # Do whatever 

pat = re.compile('[foo|bar].tralingString') 
match = pat.match(mystring) # Doesn't work 

Điều kiện duy nhất là tôi có danh sách các chuỗi phải khớp chính xác. Giải pháp tốt nhất có thể có trong Python.

EDIT: Các mẫu tìm kiếm có một số mẫu dấu thường gặp.

Trả lời

16

Bạn có thể làm một regex tầm thường kết hợp hai:

pat = re.compile('foo|bar') 
if pat.match(mystring): 
    # Do whatever 

Sau đó bạn có thể mở rộng regex để làm bất cứ điều gì bạn cần, bằng cách sử dụng | tách (có nghĩa là hoặc trong cú pháp regex)

Edit: Dựa trên chỉnh sửa gần đây của bạn, điều này sẽ làm điều đó cho bạn:

pat = re.compile('(foo|bar)\\.trailingString'); 
if pat.match(mystring): 
    # Do Whatever 

[] là một lớp nhân vật. Vì vậy, [foo|bar] của bạn sẽ khớp với một chuỗi có một của các ký tự được bao gồm (vì không có * hoặc + hoặc? Sau lớp học). () là vỏ bọc cho một mẫu phụ.

+0

Thực tế vấn đề phức tạp hơn một chút. Các mẫu tìm kiếm của tôi giống như '1. foo.trailingString 2. bar.trailingString'. Tôi đã cố gắng làm '[foo | bar] .trailingString', nhưng điều đó không thành công. – Neo

+0

@Neo: thay đổi câu hỏi, đúng không. thử '(foo | bar) .trailingString' (mặc dù tôi không chắc chắn 100% cú pháp regex của Python) ... – ircmaxell

+0

@ircmaxell: Python có cú pháp giống như PCRE chỉ với một vài khác biệt nhỏ mà tôi nghĩ. – BoltClock

7

Bạn đang sử dụng | nhưng bạn đang sử dụng lớp nhân vật [] thay vì một mẫu con (). Hãy thử regex này:

r = re.compile('(?:foo|bar)\.trailingString') 

if r.match(mystring): 
    # Do stuff 

Cũ câu trả lời

Nếu bạn muốn làm chuỗi chính xác phù hợp với bạn không nên sử dụng regex.

Hãy thử sử dụng in thay vì:

words = ['foo', 'bar'] 

# mystring contains at least one of the words 
if any(i in mystring for i in words): 
    # Do stuff 
+0

Vui lòng xem bản chỉnh sửa. Tất cả các mẫu tìm kiếm đều có một số phần đuôi phổ biến. Vì vậy, tôi đã hy vọng sử dụng Re bằng cách nào đó. – Neo

+0

@Neo: Tôi đã chỉnh sửa câu trả lời của mình. – BoltClock

0

lẽ

any([re.match(r, mystring) for r in ['bar', 'foo']]) 

Tôi giả định mô hình trận đấu của bạn sẽ phức tạp hơn foo hoặc thanh; nếu không, chỉ cần sử dụng

if mystring in ['bar', 'foo']: 
1

Sử dụng '|' trong regex của bạn. Nó là viết tắt của 'OR'. Có cách nào tốt hơn nữa, khi bạn muốn re.escape dây của bạn

pat = re.compile('|'.join(map(re.escape, ['foo.tralingString','bar.tralingString','something.else']))) 
1

Bạn có muốn tìm kiếm mẫu hoặc chuỗi?Giải pháp tốt nhất cho từng rất khác nhau:

# strings 
patterns = ['foo', 'bar', 'baz'] 
matches = set(patterns) 

if mystring in matches:  # O(1) - very fast 
    # do whatever 


# patterns 
import re 
patterns = ['foo', 'bar'] 
matches = [re.compile(pat) for pat in patterns] 

if any(m.match(mystring) for m in matches): # O(n) 
    # do whatever 

Edit: Ok, bạn muốn tìm kiếm trên chiều dài thay đổi chuỗi chính xác vào đầu của một chuỗi tìm kiếm; hãy thử

from collections import defaultdict 
matches = defaultdict(set) 

patterns = ['foo', 'barr', 'bazzz'] 
for p in patterns: 
    matches[len(p)].add(p) 

for strlen,pats in matches.iteritems(): 
    if mystring[:strlen] in pats: 
     # do whatever 
     break 
Các vấn đề liên quan