Ответ 1
Я бы предположил, что регулярное выражение лучше, чем проверка для каждой подстроки индивидуально, потому что концептуально регулярное выражение моделируется как 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)
END UPDATE
Следует отметить, что вы захотите сформировать регулярное выражение (т.е. - call to re.compile()) как можно меньше. Лучшим случаем было бы знать заранее, что ваши поиски (или вы их вычисляете один раз/нечасто), а затем сохраняете результат re.compile где-то. Мой пример - просто простая бессмысленная функция, поэтому вы можете увидеть использование регулярного выражения. Здесь есть еще несколько регулярных документов:
http://docs.python.org/library/re.html
Надеюсь, что это поможет.
UPDATE: Я не уверен, как python реализует регулярные выражения, но чтобы ответить на вопрос Rax о том, существуют ли ограничения 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)
ОБНОВЛЕНИЕ: Следует отметить, что порядок вещей ORed вместе в регулярном выражении имеет значение. Взгляните на следующий тест, вдохновленный 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
Это говорит о том, что порядок имеет значение: -/. Я не уверен, что это означает для приложения Rax, но, по крайней мере, поведение известно.
ОБНОВЛЕНИЕ: Я разместил эти вопросы о реализации регулярных выражений в Python, которые, мы надеемся, дадут нам некоторое представление о проблемах, обнаруженных с помощью этот вопрос.