Как совместить точные "множественные" строки в 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: шаблоны поиска имеют некоторые общие шаблоны.
Ответы
Ответ 1
Вы можете сделать тривиальное регулярное выражение, которое объединяет эти два:
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]
будет соответствовать строке с одним включенными символами (так как там нет * или + или? После класса). ()
- это оболочка для подматрицы.
Ответ 2
Вы правы в использовании |
, но вы используете класс символов []
вместо подшаблона ()
. Попробуйте это регулярное выражение:
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
Ответ 3
Используйте '|' в своем регулярном выражении. Это означает "OR". Также есть лучший способ, если вы хотите re.escape ваши строки
pat = re.compile('|'.join(map(re.escape, ['foo.tralingString','bar.tralingString','something.else'])))
Ответ 4
Вы хотите найти шаблоны или строки? Наилучшее решение для каждого очень сильно отличается:
# 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
Ответ 5
возможно
any([re.match(r, mystring) for r in ['bar', 'foo']])
Я предполагаю, что ваши шаблоны совпадений будут более сложными, чем foo или bar; Если это не так, просто используйте
if mystring in ['bar', 'foo']: