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

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


person Deckard    schedule 20.10.2011    source источник
comment
вы можете попробовать PHP_EOL, я считаю, что это изменит новую строку в зависимости от ОС   -  person Drewdin    schedule 20.10.2011
comment
Откуда вы это взяли, если заменить '\ r \ n' на '\ r \ n', что получится '\ r \ n \ r \ n'?   -  person N.B.    schedule 20.10.2011
comment
@ N.B. codepad.org/Qy6HpnLj   -  person ComFreek    schedule 20.10.2011


Ответы (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.

person NikiC    schedule 20.10.2011
comment
Вы также можете использовать PHP_EOL для соответствия концу файла установки. preg_replace ('~ \ R ~ u', PHP_EOL, $ строка); - person James Grundner; 21.04.2015

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

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

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

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

person Alix Axel    schedule 02.11.2011

Как насчет

$sNicetext = preg_replace('/\r\n|\r|\n/', "\r\n", $sNicetext);
person Tomalak    schedule 20.10.2011
comment
Вторая строка требует двойных кавычек;) - person NikiC; 20.10.2011
comment
Нет, это не так. ideone.com/xZLsx - Как вы думаете, зачем нужны двойные кавычки? - person Tomalak; 20.10.2011
comment
Потому что escape-последовательности разбираются только в двойных кавычках. Это нормально для регулярного выражения, потому что оно дополнительно анализирует escape-последовательности, но не для всех других строк. Таким образом, второй аргумент требует двойных кавычек, иначе вы получите простой \ r \ n вместо новой строки - person NikiC; 20.10.2011
comment
Ложь. Переменные интерполируются только в двойных кавычках. Последовательности побега работают везде. - person Tomalak; 20.10.2011
comment
@Tomalek codepad.viper-7.com/XJpmkP (И поскольку вы мне не доверяете , посмотрите документацию: php.net/manual/en/ language.types.string.php) - person NikiC; 20.10.2011
comment
Ух ты. Это ... ты только что положил это сюда! ;) Честно говоря, я совершенно удивлен. Я был настолько уверен, что интерполяция переменных была единственной разницей, что даже не стал искать ее. Хорошо спасибо. Кое-что узнал. :-) - и исправил мой пример кода. - person Tomalak; 20.10.2011

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

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

преобразовать только в LF:

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

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

person Roey    schedule 22.02.2017

$sNicetext = str_replace(["\r\n", "\r"], "\n", $sNicetext);

также работает

person Nixon Kosgei    schedule 12.01.2021
comment
Пожалуйста, добавьте пояснение к своему ответу, чтобы другие могли извлечь из него уроки. - person Nico Haase; 12.01.2021