Ответ 1
Краткий ответ
Используйте \A
to и \Z
для соответствия началу или концу строки.
Соответствующие строки из модуля re
docs:
6.2.1. Синтаксис регулярного выражения
\A
Совпадает только в начале строки.
\Z
Совпадает только в конце строки.
Предостережение о endpos
Это не сработает ", даже если кто-то использует аргумент end для re.search
".
В отличие от параметра "start" pos
, который просто отмечает начальную точку, параметр endpos
означает, что поиск (или совпадение) будет выполняться только на части строки (выделено курсором):
6.2.3. Объекты регулярного выражения
regex.search(string[, pos[, endpos]]
)Необязательный параметр
endpos
ограничивает расстояние поиска строки; это будет как если бы строка былаendpos
длинными символами, [...]rx.search(string, 0, 50)
эквивалентноrx.search(string[:50], 0)
.
\Z
соответствует концу искомой строки, что в точности соответствует endpos
.
Фон
Более знакомые ^
и $
не делают то, что вы думаете:
^
(Caret.) Соответствует началу строки, а вMULTILINE
также соответствует сразу после каждой новой строки.
$
Соответствует концу строки или непосредственно перед новой строкой в конце строки, а вMULTILINE
режим также соответствует перед новой строкой.foo
соответствует как "foo", так и "foobar", а регулярное выражениеfoo$
соответствует только "foo". Более интересно, поискfoo.$
в'foo1\nfoo2\n'
обычно соответствует "foo2", но "foo1" вMULTILINE
; поиск одного$
в'foo\n'
найдет два (пустых) совпадения: один непосредственно перед символом новой строки и один в конце строки.
Регулярные выражения Python находятся под сильным влиянием Perl, что расширяет старые возможности grep
с помощью своего собственного хозяина.
Это включало многострочное сопоставление, в котором возник вопрос о метасимволах, таких как ^
:
Соответствовало ли это началу строки или началу строки?
Когда grep
соответствует только одной строке за раз, это были эквивалентные понятия.
Как вы можете видеть, ^
и $
в конечном итоге пытались сопоставить все "start-like" и "end-ish".
Perl представил новые escape-последовательности \A
и \Z
(нижний регистр), чтобы соответствовать только началу строки и концу строки.
Эти escape-последовательности были приняты Python, но с одним отличием:
Python не принял Perl \Z
(верхний регистр), который соответствовал как конца строки, так и специальной строки newline-before-end-string...
что делает его не совсем партнером \A
, который можно было бы ожидать.
(Я предполагаю, что Perl \Z
с верхним расположением Python для последовательности, избегая однообразных регулярных выражений '\Apattern\z'
, которые были рекомендованы в таких книгах, как Perl Best Practices.)
История pos
и endpos
Похоже, что странная "не на самом деле позиция начала-начала" значения pos
столь же древняя, как и сам параметр:
-
Python 1.4
match
function docs (25 октября 1996 г. --- возможно, предварительно предваряющий объект регулярного выражения) t показывает параметрыpos
илиendpos
. -
Python 1.5
match
метод docs (17 февраля 1998 г.) представляет как объект регулярного выражения, так иpos
иendpos
. В нем указано, что^
будет соответствоватьpos
, хотя последующие версии предполагают, что это была опечатка. (Говоря о опечатках: Сам символ^
отсутствует. Он пришел и ушел, пока наконец не появился навсегда (?) В Python 2.1.) -
Python 1.5.1
match
метод docs (14 апреля 1998 г.) вставить отсутствующий "нет", отменив предыдущий документы. -
Python 1.5.1p1
match
метод docs (06 августа 1998 г.) уточняет неожиданные эффектыpos
. Они соответствуют описание Python 3.6.1pos
слово за слово... дайте или возьмите эту надоедливую^
опечатку.
Я подозреваю, что многочисленные изменения в документах за пару месяцев выпусков исправлений ошибок отражают документы, догоняющие реальность - не изменения дизайна match
(хотя у меня нет Python 1, чтобы проверить это).
python-dev
архивы списков рассылки вернутся только к 1999 году, поэтому, если предыдущие сообщения не были сохранены в другом месте, я думаю, почему "вопрос требует угадать, кто написал этот код, и спрашивать их.