如何使用RegEx以“\”转义换行符

时间:2012-11-25 10:25:30

标签: php regex

目标是将字符串拆分为行,除非前面有反斜杠。让我们想象一下。像这样的字符串:

Hello\
 world!
Bye, world.

应该拆分:

[0] Hello world!
[1] Bye, world!

我想出了这个正则表达式(对于PHP,preg_split):

/(?<!\\\\)\n/

拆分时会拆分并收回反斜杠,但是:

  • 反斜杠和换行符仍然存在。
  • 它仅适用于类UNIX的新行(\n)。

所以,它实际输出:

[0] Hello\\x10 world!
[1] Bye, world!

我的正则表达式应该如何?

到目前为止,为了解决这些问题,我尝试过:

/(?<!\\\\)(?:\r\n|\n|\r)/
/(?:(?<!\\\\)\n)/

但他们都没有工作。

2 个答案:

答案 0 :(得分:3)

您需要分两步完成:

  1. 加入行
  2. 然后拆分
  3. $text = preg_replace('/(?<!\\\\)((?:\\\\\\\\)*)\\\\((?:\n|\r)+)/', "$1", $text);
    $result = preg_split('/(\r|\n)+/', $text);
    

    第一个正则表达式确保它只在换行符之前有一个奇数个斜杠时才会拆分,因此会保留“转义斜杠”。

    因此,您可以考虑在最后用真实的反斜杠替换转义的反斜杠:

    $text = preg_replace('/(?<!\\\\)((?:\\\\\\\\)*)\\\\((?:\n|\r)+)/', "$1", $text);
    $text = preg_replace('/\\\\\\\\(?=(\\\\\\\\)*$)/m', '\\', $text);
    $result = preg_split('/\r\n?|\n/', $text);
    

答案 1 :(得分:2)

您首次尝试解决此问题已经非常好了。但你不会摆脱与分裂相同的正则表达式的换行符。您可以先在输入中使用此preg_replace(以消除转义的换行符):

$str = preg_replace('/\\\\(?:\r\n?|\n)/', '', $str);

然后用:

做一个简单的preg_split
$result = preg_split('/\r\n?|\n/', $str);

注意:您可能希望对反斜杠的位置更加宽容,以便忽略行末尾的尾随空格。这将使初始替换看起来像这样:

$str = preg_replace('/\\\\[ \t]*(?:\r\n?|\n)/', '', $str);

现在一行中的意外制表符或空格(反斜杠后)不会破坏转义。