2011-02-10 2 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.

EDIT: шаблоны поиска имеют некоторые общие шаблоны.

ответ

16

Вы могли бы сделать тривиальное регулярное выражение, которое сочетает в себе эти два:

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

Затем можно расширить регулярное выражение, чтобы делать то, что вам нужно, используя | разделитель (что означает или в регулярном выражении синтаксиса)

Edit: на основе вашего недавнего редактирования, это должно сделать это для вас:

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

+0

@Neo: это изменяет вопрос, не так ли. try '(foo | bar) .trailingString' (хотя я не уверен на 100% синтаксиса регулярного выражения Python) ... – ircmaxell

+0

@ircmaxell: Python имеет PCRE-подобный синтаксис с несколькими небольшими отличиями, которые я думаю. – BoltClock

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

Пожалуйста, взгляните на редактирование. Все шаблоны поиска имеют некоторые общие конечные части. Поэтому я как-то надеялся использовать Re. – Neo

+0

@Neo: Я отредактировал свой ответ. – BoltClock

0

возможно

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

Я предполагаю, что ваши шаблоны матч будет более сложным, чем Foo или бар; если они не являются, просто использовать

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

Использование '|' в вашем регулярном выражении. Это означает «OR». Существует лучший способ тоже, когда вы хотите, чтобы ваши строки 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 

Edit: Ok, вы хотите произвести поиск по переменной длине точных строк в начале строки поиска; попробуйте

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 
Смежные вопросы