新人公众号制作实属不易😭
希望有所收获的宝子们多多支持
↓ ↓ ↓ ↓ 后续会更新更多干货内容
Python 字符串方法全讲解:47 个方法,一次建立完整体系
一个字符串处理需求,为什么越写越像一团条件判断?
你只是想处理一批用户输入:去掉首尾空格、统一大小写、确认是不是合法编号,再从一段文本中提取信息。刚开始只有两三行代码,后来却不断加入切片、循环和 if,最后连自己都不敢轻易修改。
很多时候,问题不是字符串太难,而是你还没有建立起字符串方法的完整工具箱。清洗、查找、判断、拆分、拼接、对齐和编码,Python 都已经准备好了对应方法。
本文以 Python 3.14 为口径,把 str 的 47 个公开可调用方法按功能重新分组。你不需要一次背完;只要先理解每一组解决什么问题,再重点掌握常用方法和容易踩坑的边界,就能在需要时快速找到合适工具。
一、先记住:字符串是不可变对象
Python 字符串是 Unicode 文本组成的不可变序列。所谓不可变,就是字符串创建后,原对象中的字符不能被原地修改。
1 | text = "Hello Python" |
2 | text.strip().lower() |
3 | |
4 | print(repr(text)) |
strip() 和 lower() 都返回了新字符串,但我们没有接收结果,所以 text 仍保持原样。正确写法是重新赋值:
1 | text = "Hello Python" |
2 | text = text.strip().lower() |
3 | |
4 | print(text) |
最常见的遗漏 大多数字符串方法不会修改原字符串。调用之后如果还要使用结果,请赋值给变量、直接传给下一步,或者形成连续调用。 |

二、大小写转换:6 个方法
方法 | 作用 | 示例结果 |
upper() | 所有有大小写的字符转大写 | "hello" → "HELLO" |
lower() | 所有有大小写的字符转小写 | "HELLO" → "hello" |
capitalize() | 首字符转标题形式,其余转小写 | "hELLO WORLD" → "Hello world" |
title() | 每个单词的开头转标题形式 | "hello world" → "Hello World" |
swapcase() | 大小写互换 | "PyThOn" → "pYtHoN" |
casefold() | 更彻底地消除大小写差异 | 适合不区分大小写的比较 |
最常用的是 upper()、lower() 和 casefold():
1 | print("Python".upper()) |
2 | print("PYTHON".lower()) |
3 | print("Straße".casefold()) |
普通英文中,lower() 与 casefold() 的效果通常相同;但 casefold() 更适合做不区分大小写的文本比较。例如德语字符 ß 经过 casefold() 会变为 ss。
1 | user_input = "Straße" |
2 | expected = "STRASSE" |
3 | |
4 | print(user_input.casefold() == expected.casefold()) |
title() 看起来适合处理英文标题,但它采用通用规则判断单词边界,遇到英文缩写、撇号等情况未必符合排版习惯。它是方便工具,不是专业标题排版器。
三、查找、计数与首尾判断:7 个方法
这一组负责回答三个问题:在哪里、出现几次、是否以某内容开头或结尾。
1. find() 与 index()
1 | text = "hello python" |
2 | |
3 | print(text.find("python")) |
4 | print(text.find("java")) |
find() 找到时返回第一次出现的索引,找不到时返回 -1。index() 的查找方式相同,但找不到会抛出 ValueError。
方法 | 找到时 | 找不到时 | 适用场景 |
find() | 返回索引 | 返回 -1 | 找不到是正常分支 |
index() | 返回索引 | 抛出 ValueError | 找不到代表数据异常 |
rfind() | 返回最后一次出现的索引 | 返回 -1 | 从右侧确定最后位置 |
rindex() | 返回最后一次出现的索引 | 抛出 ValueError | 最后位置必须存在 |
四个方法都能接收 start 和 end,范围规则与切片相似:
1 | text = "cat dog cat" |
2 | |
3 | print(text.find("cat")) |
4 | print(text.rfind("cat")) |
5 | print(text.find("cat", 1, 8)) |
一个小判断 不要直接写 if text.find("python"):。当目标恰好位于索引 0 时,0 会被当作假;找不到时的 -1 反而会被当作真。应写成 if text.find("python") != -1:,或者更直接地使用 if "python" in text:。 |
2. count()、startswith() 与 endswith()
1 | filename = "report.final.pdf" |
2 | |
3 | print(filename.count(".")) |
4 | print(filename.startswith("report")) |
5 | print(filename.endswith((".pdf", ".docx"))) |
count() 统计的是不重叠的出现次数,也支持 start 和 end。startswith() 与 endswith() 除了单个字符串,还能接收字符串元组,因此很适合做扩展名白名单判断。
四、内容判断:12 个 is... 方法
判断类方法都返回布尔值。它们不会把内容转换成目标类型,只负责回答“是否满足某项规则”。
方法 | 判断内容 | 需要特别注意 |
isalpha() | 是否全部为字母 | 支持 Unicode 字母,不只 A-Z |
isalnum() | 是否全部为字母或数字 | 空字符串返回 False |
isdecimal() | 是否全部为十进制数字字符 | 三种数字判断中最严格 |
isdigit() | 是否全部为数字字符 | 范围比 isdecimal() 稍宽 |
isnumeric() | 是否全部为数值字符 | 可识别更广的 Unicode 数值字符 |
isascii() | 是否全部为 ASCII 字符 | 空字符串返回 True |
isspace() | 是否全部为空白字符 | 至少需要一个字符 |
islower() | 有大小写字符是否全部为小写 | 必须至少包含一个有大小写字符 |
isupper() | 有大小写字符是否全部为大写 | 数字和符号不会破坏判断 |
istitle() | 是否符合标题形式 | 按连续字符组判断 |
isidentifier() | 是否可作为 Python 标识符 | 关键字也可能返回 True |
isprintable() | 是否全部可打印,或为空字符串 | 换行、制表符通常不可打印 |
1. isdecimal()、isdigit()、isnumeric() 怎么选?
1 | samples = ["123", "²", "四"] |
2 | |
3 | for item in samples: |
4 | print(item, item.isdecimal(), item.isdigit(), item.isnumeric()) |
1 | 123 True True True |
2 | ² False True True |
3 | 四 False False True |
如果你要验证普通的十进制数字输入,优先考虑 isdecimal();需要识别上标数字时再考虑 isdigit();需要覆盖中文数字等更广泛的数值字符时,才使用 isnumeric()。
不过,这三个方法都不能直接判断 -3、3.14 或科学计数法,因为负号、小数点和字母并不是数字字符。真实程序中如果要判断能否转成整数或浮点数,更可靠的方式是尝试转换并捕获异常。
1 | value = "-3.14" |
2 | |
3 | try: |
4 | number= float(value) |
5 | print("可以转换:", number) |
6 | exceptValueError: |
7 | print("不是有效数字") |
2. isidentifier() 不是关键字检查器
1 | import keyword |
2 | |
3 | name = "class" |
4 | |
5 | print(name.isidentifier()) |
6 | print(keyword.iskeyword(name)) |
"class" 的形式确实符合标识符规则,所以 isidentifier() 返回 True;但它同时是 Python 保留关键字,不能直接拿来当变量名。完整判断应同时排除 keyword.iskeyword();如果还要覆盖软关键字,可继续使用 keyword.issoftkeyword()。
判断不等于转换 "123".isdecimal() 返回 True,结果仍然是字符串。需要参与数值运算时,还要使用 int() 或 float() 完成转换。 |
五、清理首尾内容:5 个方法
strip()、lstrip()、rstrip() 用于清理两端;removeprefix()、removesuffix() 用于移除明确的前缀或后缀。
1 | text = "Python" |
2 | |
3 | print(repr(text.strip())) |
4 | print(repr(text.lstrip())) |
5 | print(repr(text.rstrip())) |
1 | 'Python' |
2 | 'Python' |
3 | 'Python' |
不传参数时,它们移除空白字符。传入 chars 后,参数表示的是字符集合,不是完整前缀或后缀:
1 | url = "www.example.com" |
2 | |
3 | print(url.lstrip("cmowz.")) |
lstrip() 会不断移除左端所有属于 c、m、o、w、z、. 的字符,而不是只删除一次字符串 "cmowz."。
如果你的目标是移除一个完整、明确的前缀,应使用 removeprefix():
1 | message = "INFO: program started" |
2 | |
3 | print(message.removeprefix("INFO: ")) |
4 | print("report.csv".removesuffix(".csv")) |
需求 | 推荐方法 |
清理两端空格、换行等空白 | strip() |
清理两端某一组可能出现的字符 | strip(chars) |
只移除一个完整前缀 | removeprefix(prefix) |
只移除一个完整后缀 | removesuffix(suffix) |
版本提醒 removeprefix() 与 removesuffix() 从 Python 3.9 开始提供。如果项目仍需兼容更早版本,应使用 startswith() 或 endswith() 配合切片。 |
六、替换与批量映射:3 个方法
1. replace():直接替换子串
1 | text = "apple apple apple" |
2 | |
3 | print(text.replace("apple", "orange")) |
4 | print(text.replace("apple", "orange", 2)) |
1 | orange orange orange |
2 | orange orange apple |
第三个参数 count 用来限制最多替换多少次。即使没有匹配内容,replace() 也不会报错,只会返回内容相同的字符串。
2. maketrans() 与 translate():一次处理多种字符
str.maketrans() 创建转换表,translate() 按转换表完成替换或删除。它们适合统一标点、字符级脱敏或一次完成多组单字符转换。
1 | table = str.maketrans({ |
2 | ",": ",", |
3 | "!": "!", |
4 | "?": "?", |
5 | "#": None, |
6 | }) |
7 | |
8 | text = "你好,Python!#" |
9 | print(text.translate(table)) |
字典值为 None 表示删除对应字符。若只是替换一个固定词语,replace() 更直观;如果要同时处理多种字符,translate() 往往更清晰。
七、拆分、分区与拼接:6 个方法
文本处理最常见的主线之一,就是拆分 → 处理 → 拼接。

1. split() 与 rsplit()
1 | text = "PythonSQLExcel" |
2 | |
3 | print(text.split()) |
4 | print("a,b,c,d".split(",", 2)) |
5 | print("a,b,c,d".rsplit(",", 2)) |
1 | ['Python', 'SQL', 'Excel'] |
2 | ['a', 'b', 'c,d'] |
3 | ['a,b', 'c', 'd'] |
不传分隔符时,split() 会把连续空白视为一组,并忽略两端空白。显式传入分隔符时,连续分隔符之间会产生空字符串。
rsplit() 只有在限制拆分次数时才体现“从右侧开始”的差别;不限制次数时,它通常与 split() 得到相同结果。
2. splitlines():按行拆分
1 | text = "第一行\n第二行\r\n第三行" |
2 | |
3 | print(text.splitlines()) |
4 | print(text.splitlines(keepends=True)) |
1 | ['第一行', '第二行', '第三行'] |
2 | ['第一行\n', '第二行\r\n', '第三行'] |
keepends=True 会保留每行结尾。它比只按 "\n" 拆分更适合处理来自不同操作系统的多行文本。
3. partition() 与 rpartition()
1 | email = "alice@example.com" |
2 | |
3 | print(email.partition("@")) |
4 | print("a=b=c".rpartition("=")) |
1 | ('alice', '@', 'example.com') |
2 | ('a=b', '=', 'c') |
partition() 总是返回由“分隔符左边、分隔符本身、分隔符右边”组成的 3 元组,只分一次。rpartition() 从最后一次出现的位置分区。
对比 | split(sep, 1) | partition(sep) |
返回类型 | 列表 | 固定 3 元组 |
是否保留分隔符 | 不保留 | 保留在中间位置 |
找不到分隔符 | 返回只含原字符串的列表 | 返回原字符串和两个空字符串 |
更适合 | 需要通用拆分 | 只想取“左、中、右”三部分 |
4. join():以分隔符连接多个字符串
1 | words = ["Python", "is", "fun"] |
2 | |
3 | print(" ".join(words)) |
4 | print("-".join(words)) |
1 | Python is fun |
2 | Python-is-fun |
join() 写在分隔符字符串上,这种方向刚开始可能有些反直觉。可以把它读成:“使用这个分隔符,把后面的字符串序列连接起来。”
参与连接的元素必须都是字符串:
1 | numbers = [1, 2, 3] |
2 | result = ", ".join(map(str, numbers)) |
3 | |
4 | print(result) |
如果直接执行 ", ".join([1, 2, 3]),会抛出 TypeError。
八、对齐、补零与制表符:5 个方法
方法 | 作用 | 示例 |
center(width, fillchar) | 居中并填充 | "hi".center(6, "-") → "--hi--" |
ljust(width, fillchar) | 左对齐并填充右侧 | "hi".ljust(5, ".") → "hi..." |
rjust(width, fillchar) | 右对齐并填充左侧 | "hi".rjust(5, ".") → "...hi" |
zfill(width) | 在左侧补零,并照顾正负号 | "-42".zfill(5) → "-0042" |
expandtabs(tabsize) | 按制表位把 \t 展开为空格 | 默认制表位宽度为 8 |
1 | print("Python".center(12, "-")) |
2 | print("42".zfill(5)) |
3 | print("-42".zfill(5)) |
1 | ---Python--- |
2 | 00042 |
3 | -0042 |
如果 width 小于或等于原字符串长度,center()、ljust()、rjust() 和 zfill() 都不会截断字符串,而是返回内容相同的字符串。
expandtabs() 不是简单把每个 \t 替换成固定数量空格,而是根据当前列位置移动到下一个制表位。因此不同位置的 \t 可能展开成不同数量的空格。
九、格式化与编码:3 个方法
1. format() 与 format_map()
1 | template = "姓名:{name},得分:{score:.1f}" |
2 | |
3 | print(template.format(name="小明", score=92.56)) |
format() 接收位置参数或关键字参数;format_map() 直接接收一个映射对象:
1 | data = {"name": "小明", "city": "上海"} |
2 | template = "{name} 来自 {city}" |
3 | |
4 | print(template.format_map(data)) |
现代 Python 代码中,值已经在当前作用域时,f-string 通常更简洁;模板来自其他位置或需要复用时,format() 与 format_map() 仍然很有价值。要注意:f-string 是一种语法,不是字符串方法。
2. encode():从文本到字节
1 | text = "你好" |
2 | data = text.encode("utf-8") |
3 | |
4 | print(data) |
5 | print(type(data)) |
1 | b'\xe4\xbd\xa0\xe5\xa5\xbd' |
2 | |
encode() 返回的是 bytes,不再是 str。从字节恢复为文本时,使用的是 bytes.decode(),而不是 str 方法:
1 | data = "你好".encode("utf-8") |
2 | print(data.decode("utf-8")) |
编码边界 文本写入文件、通过网络传输或与二进制接口交互时,才需要在 str 与 bytes 之间转换。编码与解码必须使用兼容的编码方案,否则可能出现乱码或异常。 |
十、综合案例:清洗一条用户注册信息
现在把多个常用方法串起来。假设程序收到如下输入:
1 | raw = "ALICE | Alice@Example.COM | Python, SQL, python" |
目标是清理空格、统一用户名和邮箱大小写,并把技能拆分后去重。
1 | raw = "ALICE | Alice@Example.COM | Python, SQL, python" |
2 | |
3 | name_text, email_text, skills_text = ( |
4 | part.strip() |
5 | for part in raw.split("|") |
6 | ) |
7 | |
8 | name = name_text.casefold() |
9 | email = email_text.casefold() |
10 | |
11 | skills = { |
12 | skill.strip().casefold() |
13 | for skill in skills_text.split(",") |
14 | if skill.strip() |
15 | } |
16 | |
17 | print("用户名:", name) |
18 | print("邮箱:", email) |
19 | print("技能:", ", ".join(sorted(skills))) |
1 | 用户名: alice |
2 | 邮箱: alice@example.com |
3 | 技能: python, sql |
这个案例的主线很清楚:
1.使用 split() 拆开字段;
2.使用 strip() 清理两端空白;
3.使用 casefold() 统一比较口径;
4.使用集合去重;
5.使用 join() 重新组织输出。
当你发现字符串逻辑越来越乱时,可以先把任务拆成清理、判断、拆分、转换、重组几个阶段,再分别寻找对应方法。
十一、47 个字符串方法速查表
功能分类 | 方法 |
大小写转换 | capitalize()、casefold()、lower()、swapcase()、title()、upper() |
查找与计数 | count()、find()、index()、rfind()、rindex()、startswith()、endswith() |
内容判断 | isalnum()、isalpha()、isascii()、isdecimal()、isdigit()、isidentifier()、islower()、isnumeric()、isprintable()、isspace()、istitle()、isupper() |
首尾清理 | strip()、lstrip()、rstrip()、removeprefix()、removesuffix() |
替换与映射 | replace()、maketrans()、translate() |
拆分与拼接 | split()、rsplit()、splitlines()、partition()、rpartition()、join() |
对齐与填充 | center()、ljust()、rjust()、zfill()、expandtabs() |
格式化与编码 | format()、format_map()、encode() |
这张表的价值不是帮助你死记硬背,而是让你遇到问题时先定位功能分类。比如“清理开头”先看首尾清理,“确认字符串是否合法”先看内容判断,“把多段文本重新组合”先看拆分与拼接。
十二、常见错误速查
常见问题 | 容易写错 | 正确理解 |
忘记接收返回值 | text.strip() 后继续使用旧 text | 字符串不可变,应保存返回值 |
把 find() 放进布尔判断 | if text.find("x"): | 使用 in 或明确比较 != -1 |
把 strip(chars) 当成移除完整子串 | name.strip("Mr. ") | 参数是字符集合;完整前缀用 removeprefix() |
用 isdigit() 判断所有数字格式 | 期待 -3.14 返回 True | 尝试 float() 并处理 ValueError |
认为 isidentifier() 排除了关键字 | "class".isidentifier() 为 True | 还要配合 keyword.iskeyword() |
join() 中含非字符串 | ",".join([1, 2]) | 先用 map(str, values) 转换 |
混淆 str 与 bytes | 对编码结果继续用字符串方法 | encode() 后得到 bytes,解码用 bytes.decode() |
认为对齐方法会截断 | "abcdef".center(3) | 宽度不足时保留原内容 |
最后给你一个选择方法的简单路径:
·想知道“有没有、在哪里、多少次”——先看查找与计数;
·想知道“是否符合规则”——先看 is... 判断;
·想清理两端——先分清是字符集合还是完整前后缀;
·想把一段文本变成多段——用拆分或分区;
·想把多段重新连起来——用 join();
·想处理传输或文件中的字节——再考虑 encode()。
本期总结
这一期,我们把 Python 的 47 个公开字符串方法按功能重新整理,掌握了大小写转换、查找计数、内容判断、首尾清理、替换映射、拆分拼接、对齐填充、格式化和编码八条主线。
真正需要记住的不是 47 个孤立名字,而是三件事:字符串方法大多返回新值;相似方法的差别往往藏在找不到时、空字符串、Unicode 与参数含义这些边界中;复杂文本任务通常可以拆成“清理—判断—拆分—处理—拼接”的流水线。
建议你选一条真实数据,例如文件名、邮箱列表或日志内容,亲手写一遍清洗流程。用过几次之后,常用方法自然会留下来,剩下的方法只需要知道到哪里查。
END
今天的分享就到这里,感谢你耐心读到最后。希望这篇文章能帮你把零散的字符串方法整理成一套可调用的思路:遇到文本问题时,先判断属于哪一类,再选择最贴近语义的方法。我们下一期再见!
最后也想听听你的意见:下一期你希望看到哪个 Python 基础知识点? 欢迎在推文下方投票,或者在评论区留言告诉我。