为了账号安全,请及时绑定邮箱和手机立即绑定

用新行替换 \n

用新行替换 \n

PHP
青春有我 2023-03-04 17:32:10
我有一个由文本组成的字符串,可以包含多个\和n。在 php 中,使用 preg_replace,我只想在需要的地方\n替换[NewLine]。说替换\n我的意思是替换字符反斜杠-n(\和n)。我浏览了类似的问题,但没有找到一个来处理\\n不应该用新行替换的情况。例如,字符串hello\nworld应该是hello[NewLine]world,并且字符串hello\\nworld应该是hello\nworld.意义 :<?php$source1 = <<<'EOD'\nEOD;$source2 = <<<'EOD'\\nEOD;$source3 = <<<'EOD'\\\nEOD;//$source4 with 4 backslaskes , 5 with 5 etc.//preg_replace `$source1` so it ends up as `[NewLine]`//preg_replace `$source2` to `\\n`//preg_replace `$source3` to `\\[NewLine]`//etc//....//even number of consecutive \ followed by n means no [NewLine]//odd number of consecutive \ followed by n means new [NewLine]我有一个错误的替换代码$a = preg_replace('{([^{\\\}])\\\n}', "$1\n", $string); //work as expected when $string is "first-line\\nsecond-line";//doesn't work as expected when $string is "first-line\\\nsecond-line";任何人都知道在正则表达式中需要做什么才能使它正常工作?
查看完整描述

3 回答

?
蛊毒传说

TA贡献1895条经验 获得超3个赞

您可以使用回溯控制动词 跳过部分字符串(*SKIP)

$result = preg_replace('~\\\\.(*SKIP)(?<=n)~', "\n", $source);

演示

(*SKIP)当它之后的子模式失败时,跳过它之前的子模式已经到达的字符串的位置。
(?<=n)是一个回顾断言,意思是前面有 n。当它失败时,正则表达式引擎跳转到转义字符位置(由 定义的位置(*SKIP))之后进行新的尝试,而不是测试下一个位置(反斜杠之后的位置)。


您也可以使用以下方法执行相同的操作strtr

$result = strtr($source, ['\\\\' => '\\\\', '\\n' => "\n"]);

(由于为两个连续的反斜杠定义了替换,因此第二个反斜杠不能用于最终的后续n.)


查看完整回答
反对 回复 2023-03-04
?
万千封印

TA贡献1891条经验 获得超3个赞

您需要匹配成对的反斜杠\\或成对的\n. 通过指定回调,您可以检查是否需要替换它,如果不需要,只需逐字返回匹配的字符:


<?php


$inputs = [

    "\n is [NewLine]",

    "\\n is \n",

    "\\\n is \[NewLine]",

    "\n and \\n and \\\n and \\\\n"

];


$nl = function($matches) {

    return $matches[0] == "\n" ? "[NewLine]" : $matches[0];

};


print_r(preg_replace_callback("/\\\\|\\n/", $nl, $inputs));

通过将\\first 放在正则表达式交替中,它将首先被消耗,并且只有当反斜杠的数量为奇数时,才会\n匹配。


(确保转义正则表达式模式中的反斜杠!)


最后一个示例输入的输出:[NewLine] and \n and \[NewLine] and \\n


如果您的输入包含文字反斜杠字符和n(0x5c 0x6e) 而不是换行符 (0x0a)——那么您的输入是真的\\n而不是\n——您需要添加一个额外的转义级别。正则表达式变为/\\\\\\\\|\\\\n/回调必须检查"\\n"


查看完整回答
反对 回复 2023-03-04
?
慕妹3146593

TA贡献1820条经验 获得超9个赞

找到了一个更简单的解决方案。就像 knittl 所说的那样,对匹配\是关键,而 regxp 并不是真正需要的。


strtr($input, ['\\\\' => '\\','\\n' => "[NL]"]);

在https://3v4l.org/5tebZ测试



$um = [

        '\\\\' => '\\',

        '\\n' => "[NL]",

    ];


$inputs = [];

for ($i=1;$i<=14;$i++) {

   $inputs[] = ''.str_repeat("\\", $i)."n";

}


foreach ($inputs as $input) {

    $results[] = strtr($input, $um);

}


foreach ($inputs as $key=>$value)

{

    echo str_pad($value, 15, ' ',STR_PAD_LEFT)." =======> ".$results[$key]."\n";

}

输出


             \n =======> [NL]

            \\n =======> \n

           \\\n =======> \[NL]

          \\\\n =======> \\n

         \\\\\n =======> \\[NL]

        \\\\\\n =======> \\\n

       \\\\\\\n =======> \\\[NL]

      \\\\\\\\n =======> \\\\n

     \\\\\\\\\n =======> \\\\[NL]

    \\\\\\\\\\n =======> \\\\\n

   \\\\\\\\\\\n =======> \\\\\[NL]

  \\\\\\\\\\\\n =======> \\\\\\n

 \\\\\\\\\\\\\n =======> \\\\\\[NL]

\\\\\\\\\\\\\\n =======> \\\\\\\n


查看完整回答
反对 回复 2023-03-04
  • 3 回答
  • 0 关注
  • 170 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号