Соответствующие линии -\n или\r\n?
При написании этого ответа мне пришлось сопоставлять исключительно на линиях, вместо того, чтобы использовать s
-flag (dotall
- dot match linebreaks).
Сайты, обычно используемые для проверки регулярных выражений, ведут себя по-разному при попытке сопоставления на \n
или \r\n
.
Я заметил
-
Regex101 соответствует линейным ошибкам только на \n
(пример - удалить \r
, и он соответствует)
-
RegExr соответствует строкам строк ни на \n
, ни на \r\n
и я не могу найти что-то, чтобы он соответствовал линии, за исключением m
-flag и \s
(пример)
-
Debuggex ведет себя еще больше:
в в этом примере он совпадает только с \r\n
, а
здесь он соответствует только \n
, с теми же флагами и указанными движками
Я полностью осведомлен о m
-flag (multiline - make ^
соответствует началу и $
концу строки), но иногда это не вариант. То же самое с \s
, так как оно соответствует вкладкам и пробелам.
Моя мысль использовать символ новой строки unicode (\u0085
) не удалась, поэтому:
- Есть ли безопасный способ интегрировать совпадение на линии (предпочтительно независимо от используемого языка) в регулярное выражение?
- Почему вышеупомянутые сайты ведут себя по-другому (особенно Debuggex, совпадающий один раз только на
\n
и один раз только на \r\n
)?
Ответы
Ответ 1
Отвечайте в противоположном направлении;)
2) Для полного объяснения о \r и\n я должен обратиться к этому вопросу, который гораздо более полный, чем я буду здесь: Разница между \n и\г?
Короче говоря, Linux использует \n для новой строки, Windows\r\n и старых Mac\r. Таким образом, существует несколько способов написания новой строки. Ваш второй инструмент (RegExr) выполняет, например, совпадение на единственном \r.
1) [\r\n]+
, как предложил Илья, будет работать, но также будет соответствовать нескольким последовательным новым строкам. (\r\n|\r|\n)
вернее.
Ответ 2
В примерах текста в Debuggex есть разные строки. Что особенно интересно, так это то, что Debuggex, похоже, определил, какой стиль окончания строки вы использовали вначале, и он преобразует все дополнительные строки, введенные в этот стиль.
Я использовал Notepad ++ для вставки образца текста в формате Unix и Windows в Debuggex, и в зависимости от того, что я вставил первым, это то, что запустил этот сеанс Debuggex.
Итак, вы должны вымыть текст через текстовый редактор, прежде чем вставлять его в Debuggex. Убедитесь, что вы вставляете стиль, который вы хотите. По умолчанию Debuggex используется для стиля Unix (\n).
Кроме того, NEL (\ u0085) полностью отличается: https://en.wikipedia.org/wiki/Newline#Unicode
(\r?\n)
будет охватывать Unix и Windows. Вам понадобится что-то более сложное, например (\r\n|\r|\n)
, если вы хотите совместить старый Mac тоже.
Ответ 3
Это относится только к вопросу 1.
У меня есть приложение, которое работает в Windows и использует многострочный редактор MFC.
В поле редактора ожидаются строки CRLF, но мне нужно проанализировать текст, введенный
с некоторыми действительно большими/неприятными регулярными выражениями ".
Я не хотел подчеркивать это при написании регулярного выражения, так что
Я закончил нормализацию между парсером и редактором, так что
регулярные выражения просто используют \n
. Я также блокирую операции с пастой и конвертирую их в ящики.
Это не займет много времени.
Это то, что я использую.
boost::regex CRLFCRtoLF (
" \\r\\n | \\r(?!\\n) "
, MODx);
boost::regex CRLFCRtoCRLF (
" \\r\\n?+ | \\n "
, MODx);
// Convert (All style) linebreaks to linefeeds
// ---------------------------------------
void ReplaceCRLFCRtoLF( string& strSrc, string& strDest )
{
strDest = boost::regex_replace ( strSrc, CRLFCRtoLF, "\\n" );
}
// Convert linefeeds to linebreaks (Windows)
// ---------------------------------------
void ReplaceCRLFCRtoCRLF( string& strSrc, string& strDest )
{
strDest = boost::regex_replace ( strSrc, CRLFCRtoCRLF, "\\r\\n" );
}