Как заменить разные стили новой строки в PHP самым умным способом? - PullRequest
32 голосов
/ 20 октября 2011

У меня есть текст, который может иметь разные стили новой строки. Я хочу заменить все новые строки '\ 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.

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

Ответы [ 4 ]

84 голосов
/ 20 октября 2011
$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 соответствует любой последовательности новой строки 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 (вместо полного набора концов строк Юникода), установивопция 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.

15 голосов
/ 02 ноября 2011

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

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

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

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

9 голосов
/ 20 октября 2011

Как насчет

$sNicetext = preg_replace('/\r\n|\r|\n/', "\r\n", $sNicetext);
1 голос
/ 22 февраля 2017

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

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

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

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

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

...