Разница между модификаторами регулярных выражений 'm' и 's'? - PullRequest
18 голосов
/ 28 мая 2009

Я часто забываю о модификаторах регулярных выражений m и s и их различиях. Какой хороший способ запомнить их?

Насколько я понимаю, они:

'm' для многострочного, так что ^ и $ будет соответствовать началу строки и концу строки несколько раз. (как разделено \n)

's' так, что точка будет совпадать даже символ новой строки

Часто я просто использую

/some_pattern/ism

Но, вероятно, лучше использовать их соответственно (обычно в моем случае "s").

Как вы думаете, что может быть хорошим способом запомнить их, вместо того, чтобы забывать, что есть что каждый раз?

Ответы [ 3 ]

19 голосов
/ 28 мая 2009

Нередко можно встретить человека, который годами использует регулярные выражения, который до сих пор не понимает, как работают эти два модификатора. Как вы заметили, названия «многострочный» и «однострочный» не очень полезны. Они звучат так, как будто они должны быть взаимоисключающими, но они полностью независимы. Я предлагаю вам игнорировать имена и сосредоточиться на том, что они делают: m меняет поведение якорей (^ и $), а s меняет поведение точки (.).

Один выдающийся человек, который перепутал моды, является автором Ruby. Он создал свою собственную реализацию регулярных выражений, основанную на Perl, за исключением того, что он решил, что ^ и $ всегда будут якорями строки, то есть многострочный режим всегда включен. К сожалению, он также неправильно назвал режим точка-совпадения-все multiline . Таким образом, в Ruby нет модификатора s, но его модификатор m делает то же, что и s в других вариантах.

Что касается всегда использования /ism, я рекомендую против этого. Как вы уже обнаружили, он в основном безвреден, но он посылает сбивающее с толку сообщение любому, кто пытается выяснить, что регулярное выражение должно было сделать (или даже себе, в будущем).

10 голосов
/ 28 мая 2009

Мне нравится объяснение в 'man perlre':

m Обрабатывать строку как m ultiple.
s Обрабатывать строку как s одну строку.

При наличии нескольких строк ^ и $ применяются к отдельным строкам (т. Е. Непосредственно перед и после перевода строки).
В одной строке ^ и $ применяются ко всему, и \ n просто становится другим символом, которому вы можете соответствовать.

[Неверно] Используя m и s, как вы описали, я ожидаю, что второй будет иметь приоритет, поэтому вы всегда будете в многострочном режиме с /ism.[/Wrong ]

Я недостаточно далеко прочитал:
Модификаторы "/ s" и "/ m" переопределяют настройку $ *. То есть, независимо от того, что содержит $ *, «/ s» без «/ m» заставит «^» совпадать только в начале строки, а «$» - только в конце (или непосредственно перед новой строкой в конец) строки. Вместе, как / мс, они позволяют "." соответствует любому символу, в то же время позволяя сопоставлять символы «^» и «$», соответственно, сразу после и непосредственно перед символами новой строки в строке.

1 голос
/ 28 мая 2009

может быть, таким образом, я никогда не забуду:

когда я хочу сопоставить несколько строк (обычно используя. *? Для сопоставления чего-либо, что не имеет значения, если оно охватывает несколько строк), я, естественно, буду думать о многострочном, и, следовательно, «m». Ну, на самом деле «м» не тот, так что это «с».

(так как я уже хорошо помню 'ism' ... поэтому я всегда могу помнить, что это не 'm', тогда это должно быть 's').

другая неудачная попытка включает в себя:

s для DOTALL, для DOT, чтобы соответствовать ALL.
m является многострочным - для ^ и $ много раз.

...