拆行难
摘要
深入探讨在 Python 中拆分多行文本的复杂性,涵盖众多 Unicode 换行字符以及 ASCII 中换行表示的历史渊源。
<a href="https://lobste.rs/s/imdlp6/breaking_up_lines_is_hard_do">评论</a>
查看缓存全文
缓存时间: 2026/08/11 03:05
# 拆分(文本行)是件难事
来源:https://www.b-list.org/weblog/2026/aug/10/newlines/
发布于:2026 年 8 月 10 日(https://www.b-list.org/weblog/2026/aug/10/)
分类:Python(https://www.b-list.org/weblog/categories/python/)、Unicode(https://www.b-list.org/weblog/categories/unicode/)
这里有一个看似简单的问题:给定一段多行文本,如何将它拆分开来,并返回一个数组,其元素就是文本的各行?
希望你的第一反应是使用某种标准库函数,比如 Python `str` 类型的 `splitlines()` 方法。因为事实证明,这个“简单”的问题实际上相当复杂!例如,不久前我读了一篇 William Woodruff 的文章(https://yossarian.net/til/post/python-s-splitlines-does-a-lot-more-than-just-newlines/),其中指出了一个令人惊讶的发现:Python 会将多达十一个不同的 Unicode 码点或码点序列视为换行符。
当时我本打算写一篇关于这个的文章,但有很多其他事情争夺我的时间,直到现在我才终于把它从草稿中翻出来。不过,迟做总比不做好,所以今天我们就来深入探讨一下中断一行文本的多种方式,以及它们是如何被标准化、规范化,最终进入 Python 所使用的集合的。
## 一开始……
从前,有一个 ASCII。当然,在 ASCII 之前还有其他东西,与 ASCII 并存的也有,但就今天的讨论而言,我们真的只需要回到 ASCII;如果你想了解物理电传打字机的完整历史,它们如何从打字机演变而来并影响计算用字符集等,我建议你去看看维基百科。在这里,我只会略过并简化其中很多内容,以聚焦于当前的话题。
所以。从前,有一个 ASCII。它最终在计算领域变得极其有影响力和重要,其程度是其他早期字符集无法比拟的。由于它被用于那些以电传打字机(基本上是作为输入/输出设备连接的电子打字机)作为用户界面的计算机,因此包含了一些用于向电传打字机发送命令的控制字符。比如 `LINE FEED`(换行,字节值 `0x0A`)用于将纸张垂直推进到下一行,以及 `CARRIAGE RETURN`(回车,字节值 `0x0D`)用于将打印头/托架重新对齐到该行的水平起点。
它们通常缩写为 `LF` 和 `CR`(或分别用 C 系列语言中的转义序列 `\n` 和 `\r` 表示)。你可能会想,既然物理上推进打字机式设备使其准备好打印下一行需要这两种操作
相似文章
@java: 你是否还在 Java 中每行用 \n 和 + 拼接多行字符串?codebysophy 来讲解 JEP 37…
这条来自 Java 的推文重点介绍了 JEP 378,它为 Java 引入了文本块(text blocks)功能,这是一种多行字符串字面量特性,简化了跨多行编写字符串的过程,无需手动拼接和转义序列。
告别一行APL代码
作者反思了在其体素游戏中使用的一行APL代码,用于检查暴露的区块面,并解释了其灵感来源于康威生命游戏及其性能表现。
Python 字符串字面量有点搞笑
一篇博客文章,探讨 Python 原始字符串字面量和 f-string 语法中的古怪行为,包括原始字符串不能以反斜杠结尾以及 f-string 表达式可以包含注释和多行的示例。
TTY 解密 (2008)
详细解释Linux和UNIX中的TTY子系统,涵盖从电传打字机到现代模拟终端的历史,以及线路规程的作用。
非尾部分隔符并不令人愉悦
本文认为,在编程语言和数据格式中禁止尾部分隔符(如逗号)会使代码编辑更容易出错且不一致,并主张语言设计应允许尾部分隔符以提供更好的开发者体验。