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