一个新行是 \n 还是 \r\n?

62

我看到许多开发者使用不同的方法通过新行来分割字符串,但我很困惑哪个是正确的:\r\n还是\n


1
这真的取决于您正在处理的文件/字符串的格式。 - MrGlass
2
如果您想将本地系统的换行符嵌入到字符串中,可以使用PHP_EOL常量。但是,如果您正在处理来自其他系统的文本,则帮助不大。 - Marc B
你可能会发现s($str)->normalizeLineEndings()很有用,它可以在这个独立库中找到。这将把所有换行符转换为\n,即使是这个问题没有提到的Unicode换行符。 - caw
4个回答

99

\n 用于 Unix 系统(包括 Linux 和 OSX)。

\r\n 主要用于 Windows。

\r 用于旧版 Mac。

PHP_EOL 常量用来代替这些字符以实现平台间的可移植性。


1
"\r" 有时也会在当前的Mac上使用,这取决于所使用的文本编辑器。然而,大多数纯文本编辑器已经切换到Unix风格。 - ughoavgfhw
4
只是为了明确:这里所说的“非常老的 Mac”指的是编码为 OS 9 的程序,该操作系统已于2002年被宣布死亡。 - Yuji
我使用\r\n来分割MySQL中的字符串,但如果是PHP字符串,则仅使用\n有效,这很奇怪。 - CodeOverload
9
为了提供一些历史背景,这是从打印机只能打印字符的时代开始使用的。 \r 是回车符(字面意思是将打印头移动回到行的开头),\n 是换行符(将纸张向上移动)。更多信息请参见:http://en.wikipedia.org/wiki/Carriage_return。 - Chris Shain
3
关于历史方面的进一步说明,要打印一个“完整”的换行符需要两个字符的原因是因为打印头需要时间返回到行的起点,所以只需要另一个字符而不需要打印头本身做任何事情,就可以使整个系统高效地工作,无需客户端等待并在发送换行符后重新同步。 - Anon.
显示剩余3条评论

34
给出的答案远未完整。事实上,它离完整还很远,以至于读者会认为这个答案是依赖于操作系统的,但实际上并不是。它也不依赖于编程语言(正如一些评论员所建议的那样)。我将添加更多信息,以使其更清晰。首先,让我们给出当前换行符变化的列表(即自1999年以来的情况):
  • \r\n 仅用于Windows记事本(自2018年修复后),DOS命令行(PowerShell 可以很好地处理 \n;以及大多数现代版本的DOS时代命令行应用程序 [例如more]),所有在 ~2000年之前编写的 Windows API 应用程序和一些(旧的)Windows应用程序(主要是因为它们使用Windows API)。
  • 对于.ps1.bat.cmd脚本,则YMMV。
  • 奇怪的是,TCP/IP 使用 \r\n。这意味着大多数 Web 协议(包括 HTTP 本身)都使用 \r\n,正如 Raatje 所指出的那样。作为 PHP 程序员,这绝对会影响到你。
  • \n 用于所有其他系统、应用程序和网页/电子邮件内容。
你会注意到我将大多数 Windows 应用程序放在了 \n 组中,这可能有些争议,但在你反对这个说法之前,请先拿一份 UNIX 格式的文本文件并在任意10个不在我的例外列表中的 Web友好的Windows应用程序中尝试。它们中有多少能够很好地处理它?你会发现它们(几乎)都实现了换行符自动检测或者只使用 \n,因为虽然 Windows 可能使用 \r\n,但互联网和大多数其他操作系统都使用 \n。因此,如果您希望您的输出适用于互联网,请让应用程序仅使用 \n

PHP还定义了一个称为PHP_EOL的换行符号常量。在机器上设置此常量为特定于操作系统的换行字符串(对于Windows是\r\n,对于其他所有内容是\n)。该常量不适用于Web页面,并且应避免在HTML输出或撰写大多数文件文本时使用。当我们从PHP应用程序移动到命令行输出时,它变得非常有用,因为它将允许您的应用程序在所有支持的操作系统上以一致的方式输出到终端窗口。

如果您希望PHP应用程序能够在放置它们的任何服务器上工作,则需要记住两件最重要的事情:除了终端输出之外,您应始终只使用\n(在这种情况下,请使用PHP_EOL),并且您还应始终使用/作为路径分隔符(而不是\\)。第三个需要注意的是路径字符串中允许的驱动器号,这可能取决于您正在做什么。

更长的解释:

无论默认的操作系统换行样式如何,应用程序都可以选择使用任何换行符号。如果我希望我的文本编辑器在每次遇到句点时打印一个换行符,那么使用\n表示换行符并不更难,因为我在显示文本时正在解释它。也就是说,我正在测量每个字符的宽度,以便知道在哪里显示下一个,所以只需添加一条语句,如果当前字符是句点,则执行换行操作(或者如果是\n则显示句点)。

除了空结尾符外,没有任何字符代码是神圣的,当您编写文本编辑器或查看器时,您负责将文件中的位转换为屏幕上的字形(或回车)。唯一区分换行符之类的控制字符与其他字符的事情是大多数字体集不包括它们(这意味着它们没有可用的视觉表示)。

话虽如此,如果您在更高层次的抽象中工作,那么您可能不会自己制作文本框控件。 如果是这种情况,那么您只能使用该控件提供给您的任何行结束符。 即使在这种情况下,也很容易(而且相当快速)地自动检测任何字符串的行结束风格并进行相应调整。


1
你应该总是使用\n,除非它是终端输出。我本来就有这个猜想,但这种解释的清晰度正是我所需要的。 - sfarbota
3
你对语句“\n is used for all other systems, applications and the Internet.”的理解偏差了。 许多互联网协议需要使用\r\n作为行尾。 HTTP标头必须以\r\n终止,而标头和正文之间需要使用\r\n进行分隔。 - Raatje
4
请参阅HTTP(7230),SMTP(RFC5321),POP3(RFC1939)和电子邮件(RFC2822),它们规定了\r\n行结尾的MUST。 - Raatje
1
CSV规范还要求以\r\n结尾 https://tools.ietf.org/html/rfc4180#page-2 - Clement
请注意,自2018年起,记事本支持\n文件结尾。https://devblogs.microsoft.com/commandline/extended-eol-in-notepad/ - pratikpc
显示剩余2条评论

5

如果你正在使用PHP编程,将文本按照\n进行分割,然后对每一行使用trim()函数(前提是你不关心空格),可以让你得到一行“干净”的文本。

foreach($line in explode("\n", $data))
{
    $line = trim($line);
    ...
}

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接