Я бы предположил, что регулярное выражение лучше, чем проверка каждой подстроки в отдельности, потому что концептуально регулярное выражение моделируется как DFA, и, так как ввод используется, все совпадения проверяются одновременно (что приводит к одному сканированию входной строки).
Итак, вот пример:
import re
def work():
to_find = re.compile("cat|fish|dog")
search_str = "blah fish cat dog haha"
match_obj = to_find.search(search_str)
the_index = match_obj.start() # produces 5, the index of fish
which_word_matched = match_obj.group() # "fish"
# Note, if no match, match_obj is None
UPDATE:
Следует соблюдать осторожность при объединении слов в единый образец альтернативных слов. Следующий код строит регулярное выражение, но экранирует любые специальные символы регулярного выражения и сортирует слова так, чтобы более длинные слова имели возможность совпадать с любыми более короткими префиксами того же слова:
def wordlist_to_regex(words):
escaped = map(re.escape, words)
combined = '|'.join(sorted(escaped, key=len, reverse=True))
return re.compile(combined)
>>> r.search('smash atomic particles').span()
(6, 10)
>>> r.search('visit usenet:comp.lang.python today').span()
(13, 29)
>>> r.search('a north\south division').span()
(2, 13)
>>> r.search('012cat').span()
(3, 6)
>>> r.search('0123dog789cat').span()
(4, 7)
КОНЕЦ ОБНОВЛЕНИЯ
Следует отметить, что вы захотите сформировать регулярное выражение (т. Е. - вызвать re.compile ()) как можно меньше. В лучшем случае вы заранее знаете, каков ваш поиск (или вы вычисляете его один раз / не часто), а затем сохраняете результат re.compile где-нибудь. Мой пример - просто бессмысленная функция, поэтому вы можете увидеть использование регулярных выражений. Здесь есть еще несколько документов по регулярным выражениям:
http://docs.python.org/library/re.html
Надеюсь, это поможет.
ОБНОВЛЕНИЕ: Я не уверен в том, как Python реализует регулярные выражения, но чтобы ответить на вопрос Ракса о том, существуют ли ограничения re.compile () (например, как много слов, которые вы можете попробовать «|» вместе сопоставить одновременно), и количество времени для запуска компиляции: ни одно из них не кажется проблемой. Я опробовал этот код, который достаточно хорош, чтобы убедить меня. (Я мог бы сделать это лучше, добавив время и отчет о результатах, а также бросив список слов в набор, чтобы убедиться, что нет дубликатов ... но оба эти улучшения кажутся излишними). Этот код работал в основном мгновенно и убедил меня в том, что я могу искать 2000 слов (размером 10), и что они соответствуют друг другу. Вот код:
import random
import re
import string
import sys
def main(args):
words = []
letters_and_digits = "%s%s" % (string.letters, string.digits)
for i in range(2000):
chars = []
for j in range(10):
chars.append(random.choice(letters_and_digits))
words.append(("%s"*10) % tuple(chars))
search_for = re.compile("|".join(words))
first, middle, last = words[0], words[len(words) / 2], words[-1]
search_string = "%s, %s, %s" % (last, middle, first)
match_obj = search_for.search(search_string)
if match_obj is None:
print "Ahhhg"
return
index = match_obj.start()
which = match_obj.group()
if index != 0:
print "ahhhg"
return
if words[-1] != which:
print "ahhg"
return
print "success!!! Generated 2000 random words, compiled re, and was able to perform matches."
if __name__ == "__main__":
main(sys.argv)
ОБНОВЛЕНИЕ: Следует отметить, что порядок вещей ИЛИ, объединенных в регулярном выражении , имеет значение . Посмотрите на следующий тест, вдохновленный TZOTZIOY :
>>> search_str = "01catdog"
>>> test1 = re.compile("cat|catdog")
>>> match1 = test1.search(search_str)
>>> match1.group()
'cat'
>>> match1.start()
2
>>> test2 = re.compile("catdog|cat") # reverse order
>>> match2 = test2.search(search_str)
>>> match2.group()
'catdog'
>>> match2.start()
2
Это говорит о том, что порядок имеет значение: - /. Я не уверен, что это значит для приложения Ракса, но, по крайней мере, поведение известно.
ОБНОВЛЕНИЕ: Я разместил этот вопрос о реализации регулярных выражений в Python , который, мы надеемся, даст нам некоторое представление о проблемах, обнаруженных с этим вопросом.