Вопрос-Ответ

What is the difference between re.search and re.match?

В чем разница между re.search и re.match?

В чем разница между search() и match() функциями в модуле Python re?

Я читал документацию по Python 2 (документация по Python 3), но, кажется, никогда ее не запоминал.

Переведено автоматически
Ответ 1

re.match привязан к началу строки. Это не имеет ничего общего с переводом строк, поэтому это не то же самое, что использовать ^ в шаблоне.

Как говорится в документации re.match:


Если ноль или более символов в начале строки соответствуют шаблону регулярного выражения, верните соответствующий MatchObject экземпляр. Возвращает, None если строка не соответствует шаблону; обратите внимание, что это отличается от совпадения нулевой длины.


Примечание: Если вы хотите найти совпадение в любом месте строки, используйте search() вместо этого.


re.search выполняет поиск по всей строке, как сказано в документации:


Сканируйте строку в поисках местоположения, где шаблон регулярного выражения выдает совпадение, и возвращайте соответствующий MatchObject экземпляр. Возвращает, None если ни одна позиция в строке не соответствует шаблону; обратите внимание, что это отличается от поиска совпадения нулевой длины в некоторой точке строки.


Итак, если вам нужно сопоставить начало строки или всю строку целиком, используйте match. Это быстрее. В противном случае используйте search.

В документации есть специальный раздел для match vs . search, который также охватывает многострочные строки:


Python предлагает две разные примитивные операции, основанные на регулярных выражениях: match проверяет совпадение только в начале строки, в то время как search проверяет совпадение в любом месте строки (это то, что Perl делает по умолчанию).


Обратите внимание, что match может отличаться от search даже при использовании регулярного выражения, начинающегося с '^': '^' совпадает только в начале строки или в MULTILINE режиме также сразу после перевода строки. Операция “match” завершается успешно только в том случае, если шаблон совпадает в начале строки независимо от режима или в начальной позиции, заданной необязательным pos аргументом, независимо от того, предшествует ли ему перевод строки.


Итак, хватит разговоров. Пора посмотреть несколько примеров кода:

# example code:
string_with_newlines = """something
someotherthing"""


import re

print re.match('some', string_with_newlines) # matches
print re.match('someother',
string_with_newlines) # won't match
print re.match('^someother', string_with_newlines,
re.MULTILINE) # also won't match
print re.search('someother',
string_with_newlines) # finds something
print re.search('^someother', string_with_newlines,
re.MULTILINE) # also finds something

m = re.compile('thing$', re.MULTILINE)

print m.match(string_with_newlines) # no match
print m.match(string_with_newlines, pos=4) # matches
print m.search(string_with_newlines,
re.MULTILINE) # also matches
Ответ 2

search ⇒ найдите что-нибудь в любом месте строки и верните объект соответствия.

match ⇒ найдите что-нибудь в начале строки и верните объект match.

Ответ 3

сопоставление выполняется намного быстрее, чем поиск, поэтому вместо выполнения regex.search("word") вы можете выполнять regex.match((.*?)word(.*?)) и получить массу производительности, если вы работаете с миллионами выборок.


Этот комментарий от @ivan_bilan под принятым ответом выше заставил меня задуматься, действительно ли такой взлом что-либо ускоряет, поэтому давайте выясним, сколько тонн производительности вы действительно получите.

Я подготовил следующий набор тестов:

import random
import re
import string
import time

LENGTH = 10
LIST_SIZE = 1000000

def generate_word():
word = [random.choice(string.ascii_lowercase) for _ in range(LENGTH)]
word = ''.join(word)
return word

wordlist = [generate_word() for _ in range(LIST_SIZE)]

start = time.time()
[re.search('python', word) for word in wordlist]
print('search:', time.time() - start)

start = time.time()
[re.match('(.*?)python(.*?)', word) for word in wordlist]
print('match:', time.time() - start)

Я сделал 10 измерений (1 м, 2 М, ..., 10 М слов), которые дали мне следующий график:

линейный график тестирования скорости регулярных выражений в сравнении с поиском

Как вы можете видеть, поиск шаблона 'python' выполняется быстрее, чем сопоставление шаблона '(.*?)python(.*?)'.

Python умен. Не пытайтесь быть умнее.

Ответ 4

re.search поискосуществляется по шаблону по всей строке, тогда как re.match он не ищет шаблон; если это не так, у него нет другого выбора, кроме как сопоставить его в начале строки.

python regex