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
match
а не более общееsearch
? это для скорости?match
? Это умный маневр, чтобы заполнить API с неинтуитивными именами, чтобы заставить меня читать документацию? Я все еще не буду этого делать! Бунтарь!match
выглядит немного хуже,faster
чем поиск при использовании того же регулярного выражения, но ваш пример кажется неверным в соответствии с тестом производительности: stackoverflow.com/questions/180986/…search
⇒ найти что-нибудь в строке и вернуть объект соответствия.match
⇒ найти что-то в начале строки и вернуть объект соответствия.источник
re.search
поиск эс для шаблона всей строки , в то время какre.match
это не поиск шаблона; если это не так, у него нет другого выбора, кроме как сопоставить его в начале строки.источник
fullmatch
в фитоне 3.4)?Этот комментарий @ivan_bilan под принятым ответом выше заставил меня задуматься, действительно ли такой хак ускоряет что-либо, поэтому давайте выясним, сколько тонн производительности вы действительно получите.
Я подготовил следующий набор тестов:
Я сделал 10 измерений (1M, 2M, ..., 10M слов), что дало мне следующий график:
Получающиеся линии удивительно (фактически не так удивительно) прямые. И
search
функция (немного) быстрее, учитывая эту конкретную комбинацию шаблонов. Мораль этого теста: избегайте чрезмерной оптимизации вашего кода.источник
match
функция все равно быстрее, чемsearch
функция, если вы сравните одно и то же регулярное выражение. Вы можете проверить свой сценарий, сравнивre.search('^python', word)
егоre.match('python', word)
(илиre.match('^python', word)
который такой же, но легче понять, если вы не читаете документацию и, похоже, неmatch
функция, как правило, быстрее. Чемmatch
быстрее, когда вы хотите искать в начале строки, темsearch
быстрее, когда вы хотите искать по всей строке. Что соответствует здравому смыслу. Вот почему @ivan_bilan был не прав - он использовалmatch
поиск по всей строке. Вот почему вы правы - вы использовалиmatch
поиск в начале строки. Если вы не согласны со мной, попробуйте найти регулярное выражение дляmatch
этого быстрее, чемre.search('python', word)
и делает ту же работу.re.match('python')
это немного быстрее , чемre.match('^python')
. Должно быть.match
функция работает немного быстрее, если вы хотите искать в начале строки (по сравнению с использованиемsearch
функции для поиска слова в начале строки,re.search('^python', word)
например). Но я нахожу это странным, если вы скажетеsearch
функции выполнять поиск в начале строки, она должна быть такой же быстрой, как иmatch
функция.Вы можете сослаться на приведенный ниже пример, чтобы понять работу
re.match
и повторный поискre.match
вернетсяnone
, ноre.search
вернетсяabc
.источник
Разница в том, что
re.match()
вводит в заблуждение любогоre.search()
, кто привык к сопоставлению регулярных выражений Perl , grep или sed , и не делает этого. :-)Более трезво, как замечает Джон Д. Кук ,
re.match()
«ведет себя так, как будто каждый шаблон имеет ^ предваряющий». Другими словами,re.match('pattern')
равноre.search('^pattern')
. Таким образом, он закрепляет левую сторону шаблона. Но это также не привязывает правую сторону паттерна: это все еще требует завершения$
.Честно говоря, учитывая вышесказанное, я считаю, что
re.match()
это не рекомендуется. Мне было бы интересно узнать причины, по которым это следует сохранить.источник
re.match пытается сопоставить шаблон в начале строки . re.search пытается сопоставить шаблон по всей строке, пока не найдет совпадение.
источник
Намного короче:
search
просматривает всю строку.match
сканирует только начало строки.После Ex говорит это:
источник