3 回答

TA贡献1895条经验 获得超3个赞
您可以使用回溯控制动词 跳过部分字符串(*SKIP)
:
$result = preg_replace('~\\\\.(*SKIP)(?<=n)~', "\n", $source);
(*SKIP)
当它之后的子模式失败时,跳过它之前的子模式已经到达的字符串的位置。(?<=n)
是一个回顾断言,意思是前面有 n。当它失败时,正则表达式引擎跳转到转义字符位置(由 定义的位置(*SKIP)
)之后进行新的尝试,而不是测试下一个位置(反斜杠之后的位置)。
您也可以使用以下方法执行相同的操作strtr
:
$result = strtr($source, ['\\\\' => '\\\\', '\\n' => "\n"]);
(由于为两个连续的反斜杠定义了替换,因此第二个反斜杠不能用于最终的后续n
.)

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"

TA贡献1820条经验 获得超9个赞
找到了一个更简单的解决方案。就像 knittl 所说的那样,对匹配\是关键,而 regxp 并不是真正需要的。
strtr($input, ['\\\\' => '\\','\\n' => "[NL]"]);
$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
- 3 回答
- 0 关注
- 170 浏览
添加回答
举报