只是想知道当字符串包含 \n\r 时,为什么我的正则表达式给我 2 个 br 标签而不是 1 个?
我正在尝试用以下内容替换 \n、\r、\r\n 和 \n\r:
$string="testing \n\r testing2";
$result=preg_replace("/\r?\n|\n?\r/", "<br />", $string);
echo "$result";
谢谢
只是想知道当字符串包含 \n\r 时,为什么我的正则表达式给我 2 个 br 标签而不是 1 个?
我正在尝试用以下内容替换 \n、\r、\r\n 和 \n\r:
$string="testing \n\r testing2";
$result=preg_replace("/\r?\n|\n?\r/", "<br />", $string);
echo "$result";
谢谢
/\r?\n|\n?\r/
on的最佳匹配"\n\r"
是仅由第一个字符 (the \n
) 组成的子字符串。/\r?\n/
这是因为正则表达式引擎会在开始寻找 .* 的匹配项之前尝试找到一个匹配项/\n?\r/
。* 这对于匹配项总是正确的|
:匹配项之前的正则表达式部分|
优先于其之后的正则表达式匹配项。
因此,在找到第一个匹配项后,它会从上次中断的地方继续,并发现下一个字符也与正则表达式匹配。那是 2 个匹配项,每个匹配项都被替换为"<br />"
.
尝试做/\r\n?|\n\r?/
。
*(更准确地说,它会/\r?\n/
在搜索开始处锚定的匹配项之前查找在字符串开头/\n?\r/
锚定的匹配项;只有当这些搜索失败时,它才会开始查找在字符串后面锚定的匹配项。)
为什么不使用nl2br
实现相同功能的原生函数
$string="testing \n\r testing2";
echo nl2br($string);
您需要添加多行修饰符:
/\r?\n|\n?\r/ms
所以:
preg_replace("/\r?\n|\n?\r/ms", "<br />", $string);
您的表情按预期执行。再看看:
/\r?\n|\n?\r/
您似乎认为交替 ( |
) 应该有利于更长的匹配,即 \n\r
not \r
,但事实并非如此。交替匹配首先匹配的任何内容,从左到右优先。
因此,在遇到 a 时\n\r
,将\n
匹配\r?\n
并替换为<br />
,然后再次\r
匹配\n?\r
并替换。
你想要的是
/\r\n|\n\r|\r|\n/
但我认为\r\n
一般不会使用,所以
/\n\r?|\r/
应该足够了。