Clojure многострочное регулярное выражение
Я пытаюсь проверить строку для базового html-шаблона, и хотя я использую модификатор m (multiline), он работает только тогда, когда строка является 1-лайнером
(re-find #"(?im)^<html>.*<body>.*</body>.*</html>" c))
Не удается:
"<html> <body> sad </body>
</html>"
Работает:
"<html> <body> sad </body> </html>"
Что я делаю неправильно?
Ответы
Ответ 1
Отказ от ответственности: я не программист Clojure, но я думаю, что эта проблема не зависит от языка.
Когда включен многострочный режим, интерпретация каретки ^
и доллара $
изменяется следующим образом: вместо сопоставления начала и конца всей входной строки они соответствуют началу и концу каждой строки входной строки. Насколько я понимаю, это не то, что вы хотите/нужно.
То, что вы хотите, чтобы ваш .*
Соответствовал символам новой строки (что они не делают по умолчанию), и это можно сделать, включив однострочный режим (он же режим dot-all). Итак, это значит:
(re-find #"(?is)^<html>.*<body>.*</body>.*</html>" c))
Вы также можете проверить это на RegExr.
Ответ 2
Вам нужно использовать режим (?s)
"dotall mode" .
Пример:
user=> (re-find #"\d{3}.\d{3}" "123\n456")
nil
user=> (re-find #"(?s)\d{3}.\d{3}" "123\n456")
"123\n456"
Переключатель (?m)
обманчиво назван - он изменяет то, что делают якоря ^
и $
, что позволяет им также соответствовать начальным и конечным линиям, соответственно - это не хотите, чтобы вы захотели.