Как заменить разные стили Newline в 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.
Спасибо за помощь!
Решение
$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);
Это намного проще, чем регулярные выражения.