Как заменить разные стили Newline в PHP самым умным способом?

StackOverflow https://stackoverflow.com/questions/7836632

  •  27-10-2019
  •  | 
  •  

Вопрос

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

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

Это было полезно?

Решение

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

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

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

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


От PCRE DOCS:

какая \R Спички

По умолчанию последовательность r в шаблоне соответствует любой последовательности Unicode Newline, что было выбрано в качестве последовательности окончания линии. Если вы указали

     --enable-bsr-anycrlf

По умолчанию изменяется так, что r совпадает только с CR, LF или CRLF. Все, что выбрано при создании PCR, может быть переопределено при вызове библиотеки.

а также

Новые последовательности

За пределами класса символов, по умолчанию последовательность побега R соответствует любой последовательности Unicode Newline. В режиме без UTF-8 R эквивалентен следующему:

    (?>\r\n|\n|\x0b|\f|\r|\x85)

Это пример «атомной группы», детали которой приведены ниже. Эта конкретная группа совпадает с двумя символом последовательности CR с последующей LF, либо одним из отдельных символов LF (LineFeed, U+000A), VT (вертикальная вкладка, U+000B), FF (FormFeed, U+000C), CR (Возврат каретки, U+000D) или NEL (следующая линия, U+0085). Последовательность с двумя символами рассматривается как единая единица, которую нельзя разделить.

В режиме UTF-8 добавляются два дополнительных символа, коды, более 255: LS (Line Seperator, U+2028) и PS (параграф-разделитель, U+2029). Поддержка свойства симвода Unicode не нужна для распознавания этих символов.

Можно ограничить r только CR, LF или CRLF (вместо полного набора окончаний линии Unicode), установив опцию pcre_bsr_anycrlf либо во время компиляции, либо при сопоставлении шаблона. (BSR - это сокращение для «BackSlash R».) Это можно сделать по умолчанию при создании PCR; Если это так, другое поведение может быть запрошено через опцию 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, распознаются только в самом начале рисунка, и что они должны быть в верхнем случае. Если присутствует более одного из них, используется последний. Они могут быть объединены с изменением конвенции Newline; Например, шаблон может начать с:

    (*ANY)(*BSR_ANYCRLF)

Они также могут быть объединены со специальными последовательностями (*UTF8) или (*UCP). В пределах класса символов r рассматривается как непризнанная последовательность побега и поэтому соответствует букве «r» по умолчанию, но вызывает ошибку, если установлен PCRE_EXTRA.

Другие советы

Чтобы нормализовать новички, которые я всегда использую:

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

Заменяет старый Mac (\r) и окна (\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);

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top