一尘不染

如何以最聪明的方式替换PHP中的不同换行符样式?

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。

感谢您的帮助!


阅读 241

收藏
2020-05-26

共1个答案

一尘不染

$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时选择的任何内容。

换行序列

默认情况下,在字符类外部,转义序列\ 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)。不需要Unicode字符属性支持即可识别这些字符。

通过在编译时或模式匹配时设置选项PCRE_BSR_ANYCRLF,可以限制\
R仅匹配CR,LF或CRLF(而不是完整的Unicode行结尾)。(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,则会导致错误。

2020-05-26