Обновление 2020:
Я могу более четко написать, что это такое, и способ их запомнить, и я пишу это как относящееся к JavaScript:
- традиционно регулярное выражение JS не имеет флага
s
. Он имеет только флаг m
. По состоянию на январь 2020 года в Firefox его все еще нет, а в Chrome он есть. И в NodeJS это есть. Это указано в спецификациях ES2018.
s
также называют dotall
или singleline
. И действительно, .
соответствует любому (ASCII) символу, включая \n
, \r
, \u2028
(разрыв строки), \u2029
(разрыв абзаца). Когда люди спрашивают вас, чему соответствует .
? А если ответить "любой символ", то это не совсем правильно. Это все (ASCII) символы, кроме символа новой строки, \r
и разрыва строки в Юникоде и разрыва абзаца. Чтобы он соответствовал действительно всем символам ASCII, он должен иметь включенный флаг s
.
- Чтобы избежать отсутствия флага
s
в Firefox или на любой другой платформе, это могут быть [^]
, [\s\S]
, [\d\D]
и т. д. или (.|\s)
.
- Это все. Речь идет о флаге
s
, который отсутствует в традиционном JavaScript.
- Теперь флаг
m
. Это означает многострочный. И это действительно очень просто: без флага m
^
и $
будут соответствовать только началу и концу всей строки. Так что "John Doe\nMary Lee".match(/^John Doe$/)
не совпадет, а "John Doe\nMary Lee".match(/^John Doe$/m)
совпадет. Это все. Не думайте об этом слишком сложно. Это просто меняет способ сопоставления ^
и $
.
- Так являются ли «однострочный» и «многострочный» взаимоисключающими? Нет, они не. Например, если я хочу сопоставить
a
, а затем любые символы, включая новую строку и f
, но a
должно быть в начале строки, а f
должно быть в конце строки, даже если из 2000 строк текста, тогда "a b c \n d e f\nha".match(/^a.*f$/ms)
это то, что нужно использовать. Оба .
соответствуют \n
, а ^
и $
соответствуют началу строки и концу строки.
Вот и все. Вышеприведенное было протестировано на NodeJS и Chrome, которые уже поддерживают флаг s
. (а флаг m
уже давно поддерживается). И помните, вы всегда можете решить проблему отсутствия флага s
, используя [^]
Теперь, почему ms
или ism
часто использовались в прошлом? Потому что во многих случаях, когда у нас есть очень длинная строка (например, 2000 строк HTML), например, в случае некоторого веб-контента, который мы возвращаем, мы редко хотим сопоставить ^
с началом всей строки и $
с конец всей строки. Вот почему мы используем флаг m
. Теперь мы, вероятно, хотим сопоставить строки, потому что (хотя и не рекомендуется использовать регулярное выражение для сопоставления HTML), мы можем использовать /<h1>.*?</h1>/
, например, для нежадного сопоставления заголовка. Мы не возражаем против \n
в содержании, потому что у автора HTML вполне может быть \n
(или нет). Вот почему мы используем флаг «dotall» s
.
Но если вы пытаетесь извлечь некоторую информацию с веб-страницы, вам, вероятно, все равно, находится ли что-то в начале строки или в конце строки (поскольку файлы HTML могут содержать пробелы в них (или в виде отступа), и это не имеет значения). не влияет на содержимое страницы (обычно, если нет <pre>
и т. д.)), поэтому вам не нужно будет использовать ^
или $
, а значит, вы можете забыть о флаге m
. И если вы не возражаете против использования [^]*?
вместо .*?
, то можете забыть и о флаге s
— конец истории.
Perl Cookbook сказал это в двух предложениях:
Разница между /m
и /s
важна: /m
заставляет ^
и $
соответствовать новой строке, а /s
заставляет .
соответствовать новой строке. Вы даже можете использовать их вместе — это не взаимоисключающие варианты.
может так, я никогда не забуду:
когда я хочу сопоставить несколько строк (обычно используя .*? для сопоставления чего-то, что не имеет значения, если оно охватывает несколько строк), я, естественно, подумаю о многострочном и, следовательно, «m». Ну, на самом деле «м» не тот, так что это «с».
(так как я уже так хорошо помню "изм"... так что я всегда могу вспомнить, что это не "м", тогда это должно быть "с").
другая неудачная попытка включает в себя:
s
для DOTALL, это для того, чтобы DOT соответствовал ВСЕМ.
m
является многострочным -- это для ^
и $
для многократного совпадения.
person
nonopolarity
schedule
28.05.2009