Как заменить различные стили новой строки в 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.

Спасибо вам за вашу помощь!

Author: Carsten Schmitz, 2011-10-20

4 answers

$string = preg_replace('~\R~u', "\r\n", $string);

Если вы не хотите заменять все новые строки Юникода, а только строки в стиле CRLF, используйте:

$string = preg_replace('~(*BSR_ANYCRLF)\R~', "\r\n", $string);

\R соответствует этим новым строкам, u является модификатором для обработки входной строки как UTF-8.


Из Документов PCRE:

Что \R соответствует

По умолчанию последовательность \R в шаблоне соответствует любой новой строке Юникода последовательность, независимо от того, что было выбрано в качестве последовательности окончания строки. Если ты укажите

     --enable-bsr-anycrlf

Значение по умолчанию изменено таким образом, что \R соответствует только CR, LF или CRLF. Все, что выбрано при создании PCRE, может быть переопределено, когда библиотека вызываются функции.

И

Последовательности новых строк

За пределами класса символов по умолчанию escape-последовательность \R совпадает любая последовательность новой строки в Юникоде. В режиме, отличном от 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 (вместо полного набора окончаний строк в Юникоде), установив опцию 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 рассматривается как нераспознанный побег последовательность, и поэтому по умолчанию соответствует букве "R", но вызывает ошибку если задан параметр PCRE_EXTRA.

 80
Author: NikiC, 2012-01-07 14:03:08

Для нормализации новых строк я всегда использую:

$str = preg_replace('~\r\n?~', "\n", $str);

Он заменяет старые строки Mac (\r) и Windows (\r\n) на эквивалент Unix (\n).

Я предпочитаю использовать \n, потому что он занимает всего один байт вместо двух, но вы можете легко изменить его на \r\n.

 11
Author: Alix Axel, 2011-11-02 02:21:33

Как насчет

$sNicetext = preg_replace('/\r\n|\r|\n/', "\r\n", $sNicetext);
 8
Author: Tomalak, 2011-10-20 18:14:18

Я думаю, что самый умный/простой способ преобразования в CRLF:

$output = str_replace("\n", "\r\n", str_replace("\r", '', $input));

Для преобразования только в LF:

$output = str_replace("\r", '', $input);

Это намного проще, чем регулярные выражения.

 1
Author: Roey, 2017-02-22 07:49:49