Разница между модификаторами регулярных выражений '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 многострочный - это для ^ а также $ соответствовать много раз.

Другие вопросы по тегам