你先记住这个结论:Python 字符串分割日常只需要三招,按分隔符切用 split,按行切用 splitlines,规则复杂到一个固定分隔符搞不定时才用 re.split。三者都是标准库自带,从 Python 3.0 到最新版本行为都一致,不需要装任何第三方包。很多人在处理日志、CSV 文本、用户输入时习惯自己写循环加下标,结果被空字符串、连续空格、行尾换行符这些细节反复折磨。编程狮站内的字符串章节里把这类坑总结得很直白:不是方法不够用,而是你没搞清每个方法的默认行为。下面这篇笔记会把三个方法的参数、返回值、边界情况和踩坑点逐个讲清楚,每段代码都可以复制到解释器里直接跑,看完你就能在三秒内选对工具。

一、为什么需要分割字符串
绝大多数真实数据在进入程序时都是一整块文本。你从接口拿到的是 "1,2,3",从日志文件读到的是几万行拼在一起的字符串,从表单收到的是用户随手敲的一串标签。程序要做统计、要入库、要遍历,第一步必然是把这块文本切成结构化的列表,这就是 Python 字符串分割存在的全部理由。
不做分割会有什么后果?最直接的是无法索引。字符串虽然支持切片,但切片依赖固定位置,而真实数据的字段长度几乎从不固定。用户名可能三个字也可能十个字,靠 s[0:3] 取字段的代码上线第一天就会出错。分割之后拿到的是列表,你可以用下标、可以遍历、可以做列表推导,整个数据处理链路才通得起来。
第二个理由是清洗。原始文本往往夹杂多余的空格、制表符和换行符,而分割方法本身就带清洗能力。以后你会看到,不传参数的 split 会自动把连续空白当成一个分隔符并丢掉首尾空白,这一个行为就能替代好几行手写的 strip 逻辑。
第三个理由是性能与可读性的平衡。Python 的分割方法底层由 C 实现,处理十万行文本通常在毫秒级;而自己写 while 循环逐字符判断,代码长、易错、还慢。开发中有一条朴素经验:凡是标准库已经提供的字符串操作,就不要自己重新实现。理解了这三点,你再去挑具体方法时就不会纠结“到底该不该用现成函数”,而是直接进入“用哪一个”的阶段。
二、用 split() 按空白或分隔符
split 是 Python 字符串分割里最常用的方法,签名是 str.split(sep=None, maxsplit=-1),返回一个列表。它有两种截然不同的工作模式,分清这两种模式就避开了八成的坑:
s = " hello world python "
print(s.split())
# 输出: ['hello', 'world', 'python']
t = "1,2,,3,"
print(t.split(","))
# 输出: ['1', '2', '', '3', '']
print(t.split(",", 2))
# 输出: ['1', '2', ',3,']
第一种模式是不传 sep(或传 None)。此时任意长度的连续空白(空格、制表符、换行符)都被视为一个分隔符,并且首尾空白会被自动忽略,结果里绝不会出现空字符串。这正是处理“用户随手输入、空格数量不确定”场景的最佳选择。
第二种模式是显式传入分隔符,比如逗号。此时规则变成严格切分:两个逗号相邻就会产出一个空字符串,末尾有逗号也会在列表尾部留一个空串。上面例子里 t.split(",") 得到五个元素而不是三个,就是这个原因。想过滤掉空串,可以配合列表推导写成 [x for x in t.split(",") if x]。
第三个参数 maxsplit 限制最多切几次,剩下的部分整体保留在最后一个元素里,特别适合解析 key=value=xxx 这类只关心第一段的场景。另外还有一个孪生方法 rsplit,从右往左切,配合 maxsplit 可以精准取出文件扩展名。想系统过一遍这些方法的完整参数表,可以对照Python3 教程里的字符串方法章节逐个练一遍,比死记签名有效得多。
三、用 splitlines() 按行分割
处理文件内容、多行日志、粘贴进来的文本块时,真正合适的方法是 splitlines,签名是 str.splitlines(keepends=False)。它和 split("\n") 看起来像,实际差别很大:
text = "第一行\n第二行\r\n第三行\r第四行\n"
print(text.splitlines())
# 输出: ['第一行', '第二行', '第三行', '第四行']
print(text.split("\n"))
# 输出: ['第一行', '第二行\r', '第三行\r第四行', '']
print(text.splitlines(keepends=True))
# 输出: ['第一行\n', '第二行\r\n', '第三行\r', '第四行\n']
差别有三处,全都很关键。第一,splitlines 认识全部换行约定:Unix 的 \n、Windows 的 \r\n、老 Mac 的 \r 都能正确处理,而 split("\n") 只认一种,跨平台读文件时会在行尾留下看不见的 \r,导致后续比较和入库全部对不上。第二,splitlines 不会因为文本末尾有换行符就多产出一个空字符串,而 split("\n") 一定会多出来一个空串,很多“最后一行是空的”的诡异 bug 都源于这里。第三,keepends 参数可以保留行尾符,在需要原样回写文件时很有用。
顺带说一句,如果文本量非常大,逐行迭代文件对象比先读成一整块再分割更省内存,因为文件对象本身就是行迭代器。但只要文本已经在内存里,splitlines 就是最省心的选择。如果你想立刻验证上面几种输出的差异,打开Python3 在线运行把代码粘进去改换行符试几遍,比看文字描述直观十倍。
四、用 re.split() 按正则
当分隔符不是一个固定字符,而是“一类模式”时,前两个方法就不够了,这时轮到标准库 re 模块的 re.split 上场。典型场景是分隔符可能是逗号、分号、竖线里的任意一个,或者是若干个连续的非字母字符:
import re
s = "苹果, 香蕉;橘子 | 葡萄"
print(re.split(r"[,;|]\s*", s))
# 输出: ['苹果', '香蕉', '橘子 ', '葡萄']
log = "2026-09-01 10:30:00 ERROR 数据库超时"
print(re.split(r"\s+", log, maxsplit=3))
# 输出: ['2026-09-01', '10:30:00', 'ERROR', '数据库超时']
print(re.split(r"(\d+)", "abc123def"))
# 输出: ['abc', '123', 'def']
要点有三个。第一,第一个参数是正则模式,方括号表示字符集合,\s* 表示分隔符后面可以跟任意个空白,这样切出来的结果不用再逐个 strip。第二,maxsplit 的含义和 split 一致,但它是关键字参数,从 Python 3.13 起位置传参已被移除,写成 maxsplit=3 才稳妥。第三,如果模式里带了捕获组(括号),分隔符本身也会出现在结果列表里,这个特性可以用来做“既要切开又要保留标记”的解析,但不小心加括号就会得到意外的额外元素。
代价是性能与可读性。正则的执行开销明显高于 split,在百万行级循环里差距会被放大,所以能用固定分隔符解决的场景就别上正则。另一个常见误用是拿 re.split 解析 CSV:真实 CSV 里带引号的字段内部可能含逗号,正则很难正确处理,这种情况应该直接用标准库的 csv 模块。选择正则的判断标准很简单——分隔符是否真的存在多种形态,如果只有一种,Python 字符串分割用 split 就够了。
五、三种方式怎么选
把三个方法收敛成一条决策链,你以后不用再犹豫。第一步先问:要切的是行吗?是就用 splitlines,因为它同时解决了跨平台换行和末尾空串两个问题,没有任何替代品比它更合适。第二步再问:分隔符是不是一个固定的字符或字符串?是就用 split,需要时补上 maxsplit 限制次数、或改用 rsplit 从右侧切;如果只是想按空白切并顺手清洗,直接不传参数即可。第三步,只有当分隔符存在多种形态、或者需要在切分时保留标记,才动用 re.split。
再补两条经验。一是分割之后几乎总要做一次过滤和去空白,标准写法是 [x.strip() for x in parts if x.strip()],把它当成肌肉记忆写下来,能省掉大量偶发的空元素 bug。二是分隔符要尽量选数据里绝不会出现的字符;如果业务字段本身可能含逗号,那就换成制表符或者干脆改用 json 传输,靠正则打补丁只会越补越乱。
顺便说一个学习方法:把这三个方法在编程狮站内的 python3教程 页面里对照着各写五个例子,包括故意构造空串、连续分隔符、末尾分隔符这些边界输入,看清它们的输出差异。Python 字符串分割的语法只有三行,真正的功力全在边界处理上,动手写过一遍你才会记住。

总结
Python 字符串分割的三种方法各有明确定位:split 处理固定分隔符,不传参数时自动合并连续空白并丢弃首尾空白,传入分隔符后则严格切分、会保留空字符串;splitlines 专门处理换行,能同时识别 \n、\r\n、\r 三种约定且不会在末尾多出空串;re.split 用正则应对多形态分隔符,代价是性能开销和捕获组带来的额外元素。选择顺序永远是“先看是否按行、再看分隔符是否固定、最后才考虑正则”,并且分割后统一做一次 strip 与空值过滤。把这条链路固化成习惯,你在处理日志、表单、配置文本时基本不会再翻车。
延伸学习
- 课程:Python3 入门到爬虫实战课程
- 笔记:Python 列表元素计数笔记
- 教程:Python 速查手册
常见问题
Q:split() 和 splitlines() 到底该用哪个切换行?
A:结论:切行一律用 splitlines。
split("\n") 只认单一换行符,遇到 Windows 的 \r\n 会在每行尾部留下 \r,而且文本末尾有换行时会多出一个空字符串。
splitlines 同时识别三种换行约定且不产生末尾空串,需要保留行尾符时传 keepends=True 即可。
Q:为什么 "1,2,,3".split(",") 会出现空字符串?
A:结论:传入分隔符后 split 走严格切分模式。
两个分隔符相邻,中间那段本来就是空文本,所以列表里如实出现一个空串,这是设计而非缺陷。
想过滤掉就写 [x for x in s.split(",") if x],或者在数据源头保证不出现连续分隔符。
Q:re.split() 比 split() 慢很多吗?
A:结论:慢,但只在大数据量下才需要在意。
正则要先编译再逐字符匹配,单次调用开销通常是 split 的几倍,处理几百行完全无感。
如果在百万级循环里使用,建议先用 re.compile 预编译模式复用,或者退回固定分隔符方案。
Q:分割 CSV 文件能直接用 split(",") 吗?
A:结论:不能,应当使用标准库 csv 模块。
真实 CSV 允许字段用双引号包裹,引号内部的逗号不是分隔符,任何简单分割都会把这类字段切坏。
csv 模块还会处理转义引号与内嵌换行,比自己拼正则可靠得多。

免费 AI IDE



