Как заменить разные стили новой строки в PHP самым умным способом?
У меня есть текст, который может иметь разные стили новой строки. Я хочу заменить все новые строки '\ r \n', '\ n', '\ r' одинаковыми символами новой строки (в данном случае \r\n).
Какой самый быстрый способ сделать это? Мое текущее решение выглядит примерно так:
$sNicetext = str_replace("\r\n",'%%%%somthing%%%%', $sNicetext);
$sNicetext = str_replace(array("\r","\n"),array("\r\n","\r\n"), $sNicetext);
$sNicetext = str_replace('%%%%somthing%%%%',"\r\n", $sNicetext);
Проблема в том, что вы не можете сделать это с одной заменой, потому что \ r \ n будет дублироваться в \r\n\r\n .
Спасибо за помощь!
5 ответов
$string = preg_replace('~\R~u', "\r\n", $string);
Если вы не хотите заменять все символы новой строки Unicode, а только строки стиля CRLF, используйте:
$string = preg_replace('~(*BSR_ANYCRLF)\R~', "\r\n", $string);
\R
соответствует этим символам новой строки, u
является модификатором для обработки входной строки как UTF-8.
Из документов PCRE:
Какие
\R
МатчиПо умолчанию последовательность \R в шаблоне соответствует любой последовательности новой строки Unicode, независимо от того, какая из них была выбрана в качестве конечной последовательности строки. Если вы укажете
--enable-bsr-anycrlf
значение по умолчанию изменено так, что \R соответствует только CR, LF или CRLF. Все, что выбрано при сборке PCRE, может быть переопределено при вызове функций библиотеки.
а также
Последовательности новой строки
По умолчанию за пределами класса символов escape-последовательность \R соответствует любой последовательности новой строки Unicode. В не-UTF-8 режиме \R эквивалентно следующему:
(?>\r\n|\n|\x0b|\f|\r|\x85)
Это пример "атомной группы", подробности о которой приведены ниже. Эта конкретная группа соответствует либо двухсимвольной последовательности CR, за которой следует LF, либо одному из одиночных символов LF (перевод строки, U+000A), VT (вертикальная табуляция, U+000B), FF (подача формы, U+000C), CR (возврат каретки, U+000D) или NEL (следующая строка, U+0085). Двухсимвольная последовательность рассматривается как единое целое, которое не может быть разделено.
В режиме UTF-8 добавляются два дополнительных символа, кодовые точки которых превышают 255: LS (разделитель строк, U+2028) и PS (разделитель абзацев, U+2029). Для распознавания этих символов поддержка свойств символов Юникода не требуется.
Можно ограничить \R для соответствия только CR, LF или CRLF (вместо полного набора концов строк Unicode), установив параметр PCRE_BSR_ANYCRLF либо во время компиляции, либо при сопоставлении с шаблоном. (BSR - это сокращение от "обратный слеш R".) Это может быть сделано по умолчанию при сборке PCRE; если это так, другое поведение может быть запрошено с помощью опции PCRE_BSR_UNICODE. Также можно указать эти настройки, запустив строку шаблона с одной из следующих последовательностей:
(*BSR_ANYCRLF) CR, LF, or CRLF only (*BSR_UNICODE) any Unicode newline sequence
Они переопределяют значения по умолчанию и параметры, заданные для pcre_compile() или pcre_compile2(), но они могут быть переопределены параметрами, заданными pcre_exec() или pcre_dfa_exec(). Обратите внимание, что эти специальные настройки, которые не совместимы с Perl, распознаются только в самом начале шаблона, и что они должны быть в верхнем регистре. Если присутствует более одного из них, используется последний. Они могут быть объединены с изменением соглашения новой строки; например, шаблон может начинаться с:
(*ANY)(*BSR_ANYCRLF)
Их также можно комбинировать со специальными последовательностями (*UTF8) или (*UCP). Внутри символьного класса \R обрабатывается как нераспознанная escape-последовательность и поэтому по умолчанию соответствует букве "R", но вызывает ошибку, если установлен PCRE_EXTRA.
Для нормализации новых строк я всегда использую:
$str = preg_replace('~\r\n?~', "\n", $str);
Заменяет старый Mac (\r
) и Windows (\r\n
) переводы строки с эквивалентом Unix (\n
).
Я предпочитаю использовать \n
потому что он занимает только один байт вместо двух, но вы можете легко изменить его на \r\n
,
Как насчет
$sNicetext = preg_replace('/\r\n|\r|\n/', "\r\n", $sNicetext);
Я думаю, что самый умный / простой способ конвертировать в CRLF это:
$output = str_replace("\n", "\r\n", str_replace("\r", '', $input));
конвертировать только в LF:
$output = str_replace("\r", '', $input);
это намного проще, чем регулярные выражения.
$sNicetext = str_replace(["\r\n", "\r"], "\n", $sNicetext);
также работает