2011-02-10 61 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