Разница между модификаторами регулярных выражений 'm' и 's'?
Я часто забываю о модификаторах регулярных выражений m
а также s
и их различия. Какой хороший способ запомнить их?
Как я понимаю их, они:
"м" для многострочного, так что
^
а также$
будет совпадать с началом строки и концом строки несколько раз. (делится на\n
)'s' означает, что точка будет соответствовать даже символу новой строки
Часто я просто использую
/some_pattern/ism
Но, вероятно, лучше использовать их соответственно (обычно "s" в моих случаях).
Как вы думаете, что может быть хорошим способом запомнить их, вместо того, чтобы забывать, что есть каждый раз?
3 ответа
Нередко можно встретить человека, который годами использует регулярные выражения, но до сих пор не понимает, как работают эти два модификатора. Как вы заметили, названия "многострочный" и "однострочный" не очень полезны. Они звучат так, как будто они должны быть взаимоисключающими, но они полностью независимы. Я предлагаю вам игнорировать имена и сосредоточиться на том, что они делают: m
меняет поведение якорей (^
а также $
), а также s
меняет поведение точки (.
).
Один выдающийся человек, который перепутал моды, является автором Ruby. Он создал свою собственную реализацию регулярных выражений, основанную на Perl, за исключением того, что он решил иметь ^
а также $
всегда быть якорями линии, то есть многострочный режим всегда включен. К сожалению, он также неправильно назвал многострочным режим точка-совпадения-все. Так что у Руби нет s
модификатор, но его m
модификатор делает то, что s
делает в других ароматах.
Как всегда использовать /ism
Рекомендую против этого. Как вы уже обнаружили, он в основном безвреден, но он посылает запутанное сообщение всем, кто пытается выяснить, что регулярное выражение должно было сделать (или даже себе, в будущем).
Мне нравится объяснение в "man perlre":
m Обрабатывать строку как m нескольких строк.
Обрабатывать строку как одну строку.
С несколькими строками ^ и $ применяются к отдельным строкам (то есть непосредственно перед и после перевода строки).
В одной строке ^ и $ применяются ко всему, и \n просто становится другим символом, которому вы можете соответствовать.
[Неверно] Используя m и s, как вы описали, я ожидаю, что второй будет иметь приоритет, поэтому вы всегда будете в многострочном режиме с / ism. [/Неправильно]
Я не прочитал достаточно далеко:
Модификаторы "/s" и "/m" переопределяют настройку $*. То есть, независимо от того, что содержит $*, "/s" без "/m" заставит "^" совпадать только в начале строки, а "$" - только в конце (или непосредственно перед новой строкой в конец) строки. Вместе, как / мс, они позволяют "." соответствует любому символу, в то же время позволяя сопоставлять "^" и "$", соответственно, сразу после и непосредственно перед символами новой строки в строке.
Может быть, таким образом, я никогда не забуду
когда я хочу сопоставить несколько строк (обычно используя.*? для сопоставления чего-либо, что не имеет значения, если оно охватывает несколько строк), я, естественно, подумаю о многострочном, и, следовательно, 'm'. Ну, на самом деле "м" не тот, так что это "с".
(так как я уже хорошо помню 'ism'... так что я всегда могу помнить, что это не 'm', тогда это должно быть 's').
другая неудачная попытка включает в себя:
s
для DOTALL, для DOT, чтобы соответствовать ВСЕ.m
многострочный - это для ^
а также $
соответствовать много раз.