Подтвердить что ты не робот

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

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

Я прочитал документацию ( текущая документация), но я никогда не помню его. Я продолжаю искать и переучивать его. Я надеюсь, что кто-то ясно ответит на это примерами, чтобы (возможно) это застряло у меня в голове. Или, по крайней мере, у меня будет лучшее место, чтобы вернуться с моим вопросом, и для его изучения потребуется меньше времени.

4b9b3361

Ответ 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" операция выполняется только в том случае, если шаблон совпадает со строкой startнезависимо от режима, или при запуске положение, заданное опционным 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 → найти что-то в начале строки и вернуть объект соответствия.

Ответ 3

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

Ответ 4

  сопоставление выполняется намного быстрее, чем поиск, поэтому вместо выполнения 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 измерений (1M, 2M,..., 10M слов), что дало мне следующий график:

match vs. search regex speedtest line plot

Получающиеся линии удивительно (фактически не так удивительно) прямые. И функция search (немного) быстрее, учитывая эту конкретную комбинацию паттернов. Мораль этого теста: избегайте чрезмерной оптимизации вашего кода.

Ответ 5

Разница заключается в том, что re.match() вводит в заблуждение любого, кто привык к сопоставлению регулярных выражений Perl, grep или sed, а re.search() - нет.: -)

Более трезвый, Как замечает Джон Д. Кук, re.match() "ведет себя так, как если бы каждый шаблон имел" добавленный". Другими словами, re.match('pattern') равно re.search('^pattern'). Таким образом, он фиксирует левую сторону шаблона. Но он также не привязывает правую сторону шаблона: это все еще требует завершения $.

Откровенно говоря, я сказал, что re.match() должен быть устаревшим. Мне было бы интересно узнать причины, по которым его следует сохранить.

Ответ 6

Вы можете обратиться к приведенному ниже примеру, чтобы понять работу re.match и re.search

a = "123abc"
t = re.match("[a-z]+",a)
t = re.search("[a-z]+",a)

re.match вернет none, но re.search вернет abc.

Ответ 7

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

Ответ 8

Намного короче:

  • search сканирует всю строку.

  • match Делает только начало строки.

После Ex говорит это:

>>> a = "123abc"
>>> re.match("[a-z]+",a)
None
>>> re.search("[a-z]+",a)
abc