2011-02-10 59 views
10

我有一個確切模式的列表,我想在給定的字符串中搜索。目前,我對這個問題有一個真正的不好的解決方案。如何在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 

唯一的條件是我有一個準確匹配的字符串列表。 Python中最好的解決方案是什麼?

編輯:搜索模式有一些共同的拖尾模式。

回答

16

你可以做一個簡單的正則表達式,結合這兩個:

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

然後,您可以展開正則表達式做任何你需要使用|分離器(這意味着或正則表達式語法

編輯:基於您近期的編輯,這應該爲你做它:

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

[]是一個角色類。所以你的[foo|bar]會匹配一個字符串與一個包括的字符(因爲沒有*或+或?在課後)。 ()是子模式的外殼。

+0

其實問題有點複雜。我的搜索模式像`1。 foo.trailingString 2. bar.trailingString`。我試圖做`[foo | bar] .trailingString`,但是失敗了。 – Neo 2011-02-10 04:15:35

+0

@Neo:這改變了問題,不是。嘗試`(foo | bar).trailingString`(儘管我不是100%確定Python的正則表達式語法)...... – ircmaxell 2011-02-10 04:17:04

7

你是對的,使用|,但你正在使用字符類[],而不是子模式()。試試這個正則表達式:如果你想要做精確的子

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

if r.match(mystring): 
    # Do stuff 

老答案

匹配你不應該使用正則表達式。

嘗試使用in代替:

words = ['foo', 'bar'] 

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

也許

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

我假設你的匹配模式會比富或酒吧更復雜;如果不是,只需使用

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

使用'|'在您的正則表達式。它代表'或'。有更好的辦法也一樣,當你想re.escape你的字符串

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

你要搜索模式?對於每一個最好的解決方案有很大的不同:

# 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 

編輯:好吧,你想上的搜索字符串的開頭可變長度精確匹配搜索;嘗試

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