python字符串用来保存文本。姓名、文件路径、网页地址和接口返回的消息,只要内容是文字,在 Python 中通常都会使用字符串处理。
思维导图

这一章主要讲字符串的创建、索引、切片、常用方法和格式化。字符串看起来简单,不过索引越界、转义字符、split() 和 join() 的用法,以及字符串不可变这些地方都比较容易写错。

一、创建字符串
Python 中的字符串类型是 str,可以使用单引号、双引号或者三引号创建:
python
name = 'Ivan'
language = "Python"
message = """这是一个
可以换行的字符串"""
单引号和双引号没有类型上的区别,选择哪一种主要看字符串中包含什么内容。例如,字符串里已经有单引号时,外面使用双引号会方便一些:
python
message = "I'm learning Python"
如果字符串里有双引号,也可以反过来写:
python
message = '他说:"今天开始学习 Python。"'
三引号可以保存跨越多行的文本,其中的换行也会成为字符串内容的一部分:
python
text = """第一行
第二行
第三行"""
print(text)
输出结果为:
txt
第一行
第二行
第三行
空字符串中没有任何字符,但是它仍然是一个字符串对象:
python
empty_text = ""
print(type(empty_text))
print(len(empty_text))
输出结果为:
txt
<class 'str'>
0
二、转义字符与原始字符串
反斜杠 \ 在字符串中用来表示一些不能直接写出来,或者具有特殊含义的字符。
| 写法 | 含义 |
|---|---|
\n |
换行 |
\t |
制表符 |
\\ |
一个反斜杠 |
\' |
单引号 |
\" |
双引号 |
\r |
回车 |
例如:
python
message = "姓名:Ivan\n语言:Python"
print(message)
输出结果为:
txt
姓名:Ivan
语言:Python
1. 路径中的反斜杠
Windows 路径中经常出现反斜杠。如果直接写路径,其中的 \n、\t 等组合可能会被当成转义字符:
python
path = "C:\new\test.txt"
print(path)
这段代码不会按照原路径输出,因为 \n 会换行,\t 会变成制表符。可以把每个反斜杠再转义一次:
python
path = "C:\\new\\test.txt"
也可以在字符串前加上 r,创建原始字符串:
python
path = r"C:\new\test.txt"
print(path)
原始字符串会保留大多数反斜杠。不过它不能以单个反斜杠结尾,下面的写法会出现语法错误:
python
# 错误写法
path = r"C:\new\"
处理路径时,更常见的办法是使用标准库中的 pathlib。这一部分会放到文件操作章节中再讲。

三、字符串索引
字符串由一个个字符组成,每个字符都有自己的位置,这个位置称为索引。Python 的索引从 0 开始:
python
text = "Python"
print(text[0])
print(text[1])
print(text[5])
输出结果为:
txt
P
y
n
也可以使用负数索引从右向左读取字符。最后一个字符的索引是 -1:
python
print(text[-1])
print(text[-2])
print(text[-6])
输出结果为:
txt
n
o
P
len() 可以取得字符串的字符数量:
python
text = "Python"
print(len(text))
结果为 6,所以它能使用的正数索引是 0 到 5。访问不存在的位置会引发 IndexError:
python
print(text[6])
中文字符也按照字符数量计算:
python
text = "学习Python"
print(len(text))
print(text[0])
输出结果为:
txt
8
学
这里的 len() 计算的是字符数量,不是字符串保存到文件以后占用的字节数。
四、字符串切片
索引一次只能取得一个字符,切片可以取出一段字符串。基本写法如下:
python
字符串[开始位置:结束位置:步长]
切片包含开始位置,不包含结束位置。例如:
python
text = "Python"
print(text[0:2])
print(text[2:6])
输出结果为:
txt
Py
thon
text[0:2] 取得索引 0 和 1,不会取得索引 2。这种规则也常写成"左闭右开"。
1. 省略开始或结束位置
省略开始位置时,默认从字符串开头切:
python
print(text[:3])
输出 Pyt。
省略结束位置时,会一直切到字符串末尾:
python
print(text[3:])
输出 hon。
开始和结束都省略时,会得到完整字符串:
python
print(text[:])
2. 使用负数索引切片
负数索引也可以放在切片中:
python
filename = "report.pdf"
print(filename[-3:])
print(filename[:-4])
输出结果为:
txt
pdf
report
3. 设置步长
第三个参数表示每隔几个字符取一次:
python
text = "0123456789"
print(text[::2])
print(text[1::2])
输出结果为:
txt
02468
13579
步长为负数时,会从右向左取字符。下面的写法可以把字符串倒过来:
python
text = "Python"
print(text[::-1])
输出结果为 nohtyP。
与单个索引不同,切片超出字符串范围通常不会报错:
python
text = "Python"
print(text[0:100])
结果仍然是 Python。Python 会在字符串实际结束的位置停下来。

五、字符串是不可变对象
字符串创建以后,其中的字符不能直接修改。下面的代码会出现 TypeError:
python
text = "Python"
text[0] = "J"
如果想把 Python 改成 Jython,需要创建一个新的字符串,再让变量指向它:
python
text = "Python"
text = "J" + text[1:]
print(text)
字符串方法也是一样。例如,replace() 返回修改后的新字符串,并不会在原字符串上直接修改:
python
text = "I like Java"
new_text = text.replace("Java", "Python")
print(text)
print(new_text)
输出结果为:
css
I like Java
I like Python
如果后面的代码要继续使用替换结果,就要接收它的返回值:
python
text = text.replace("Java", "Python")

六、字符串的基本运算
1. 拼接字符串
+ 可以拼接多个字符串:
python
first_name = "Ivan"
last_name = "Chen"
full_name = first_name + " " + last_name
print(full_name)
字符串不能直接和数字拼接:
python
age = 20
# 错误写法
message = "年龄:" + age
可以先使用 str() 转换,也可以直接使用 f-string:
python
message1 = "年龄:" + str(age)
message2 = f"年龄:{age}"
2. 重复字符串
* 可以把字符串重复指定次数:
python
line = "-" * 20
print(line)
3. 判断是否包含
in 和 not in 可以判断字符串中是否包含一段内容:
python
url = "https://www.python.org"
print("python" in url)
print("java" not in url)
字符串判断区分大小写:
python
print("Python" in "python.org")
结果为 False。
4. 比较字符串
字符串可以使用 ==、!=、<、> 等运算符比较:
python
print("Python" == "Python")
print("Python" == "python")
print("apple" < "banana")
大小比较会按照字符的 Unicode 编码顺序逐个比较,不等同于汉语拼音、字典顺序或者自然语言中的大小关系。业务代码需要排序中文、忽略大小写或处理不同语言时,通常要增加专门的规则。
七、查找与统计
1. find() 与 rfind()
find() 返回指定内容第一次出现的索引,没有找到时返回 -1:
python
text = "Python is easy, Python is useful"
print(text.find("Python"))
print(text.find("Java"))
输出结果为:
txt
0
-1
rfind() 从右侧开始查找,所以它会返回最后一次出现的位置:
python
print(text.rfind("Python"))
2. index() 与 rindex()
index() 的结果与 find() 类似,不过没有找到时会引发 ValueError:
python
text = "Python"
print(text.index("th"))
是否使用 find() 或 index(),要看没有找到是不是正常情况。如果没有找到也允许继续运行,find() 通常更方便;如果没有找到说明数据本身有问题,可以使用 index(),再交给异常处理代码处理。
3. count()
count() 用来统计某段内容出现的次数:
python
text = "banana"
print(text.count("a"))
print(text.count("an"))
输出结果为:
txt
3
2
4. startswith() 与 endswith()
这两个方法用来判断字符串的开头和结尾:
python
filename = "report.pdf"
print(filename.startswith("report"))
print(filename.endswith(".pdf"))
也可以传入一个元组,同时判断多个候选值:
python
filename = "photo.png"
is_image = filename.endswith((".jpg", ".jpeg", ".png", ".gif"))
print(is_image)
八、大小写与空白处理
1. 大小写转换
常用的大小写方法如下:
| 方法 | 作用 |
|---|---|
lower() |
转为小写 |
upper() |
转为大写 |
capitalize() |
首字符大写,其余字符小写 |
title() |
每个单词的首字母大写 |
swapcase() |
交换大小写 |
casefold() |
用于不区分大小写的文本比较 |
python
text = "Hello Python"
print(text.lower())
print(text.upper())
print(text.title())
如果只是进行简单的英文大小写转换,lower() 已经够用。需要比较不同语言的文本时,casefold() 处理得更彻底:
python
left = "Straße"
right = "STRASSE"
print(left.casefold() == right.casefold())
结果为 True。
2. 去掉两端字符
strip() 去掉字符串两端的空白,lstrip() 只处理左侧,rstrip() 只处理右侧:
python
text = " Python \n"
print(repr(text.strip()))
print(repr(text.lstrip()))
print(repr(text.rstrip()))
这里使用 repr() 输出,是为了让空格和 \n 更容易看出来。
strip() 也可以接收参数,不过参数表示一组需要从两端删除的字符,并不是完整的前缀或后缀:
python
text = "www.example.com"
print(text.strip("w.com"))
这段代码会不断删除两端属于 w、.、c、o、m 的字符,结果可能和预想的不一样。删除固定前缀或后缀时,应该使用:
python
url = "https://example.com"
print(url.removeprefix("https://"))
filename = "report.pdf"
print(filename.removesuffix(".pdf"))
九、替换、拆分与连接
1. replace()
replace() 用来替换字符串中的内容:
python
text = "Java is useful"
new_text = text.replace("Java", "Python")
print(new_text)
第三个参数可以限制替换次数:
python
text = "one one one"
print(text.replace("one", "two", 2))
输出结果为 two two one。
2. split()
split() 按照指定分隔符把字符串拆成列表:
python
text = "Python,Java,Go"
languages = text.split(",")
print(languages)
输出结果为:
txt
['Python', 'Java', 'Go']
不传分隔符时,split() 会按照连续的空白字符拆分,并忽略两端空白:
python
text = " Python Java\tGo "
print(text.split())
输出结果为:
txt
['Python', 'Java', 'Go']
如果明确传入一个空格,规则就不同了,连续空格会产生空字符串:
python
text = "Python Java"
print(text.split(" "))
输出结果为:
txt
['Python', '', '', 'Java']
maxsplit 可以限制最多拆分几次:
python
record = "2026-08-21-error-message"
print(record.split("-", 3))
3. splitlines()
splitlines() 按照换行符拆分多行文本:
python
text = "第一行\n第二行\n第三行"
print(text.splitlines())
4. join()
join() 把多个字符串连接起来:
python
languages = ["Python", "Java", "Go"]
text = ", ".join(languages)
print(text)
输出结果为:
txt
Python, Java, Go
调用 join() 的对象是分隔符,因此写法是 "分隔符".join(字符串序列)。列表里如果有整数,需要先转换为字符串:
python
numbers = [10, 20, 30]
# 错误写法
# text = ",".join(numbers)
text = ",".join(str(number) for number in numbers)
print(text)
这里暂时用到了一个生成器表达式。现阶段只需要知道,它会把列表中的每个数字交给 str() 转换;具体语法会在推导式与生成器章节中再讲。

十、判断字符串内容
Python 提供了一组以 is 开头的方法,用来判断字符串是否符合某种形式:
| 方法 | 判断内容 |
|---|---|
isalpha() |
是否全部为字母且至少有一个字符 |
isdigit() |
是否全部为数字字符且至少有一个字符 |
isdecimal() |
是否全部为十进制数字字符 |
isalnum() |
是否全部由字母或数字组成 |
isspace() |
是否全部为空白字符 |
islower() |
是否包含字母且字母都是小写 |
isupper() |
是否包含字母且字母都是大写 |
istitle() |
是否符合标题大小写形式 |
python
print("Python".isalpha())
print("2026".isdigit())
print("Python3".isalnum())
print(" \n".isspace())
这些方法的结果都是布尔值。需要注意,isdigit() 识别的数字字符范围比普通的 0 到 9 更广,所以它不能替代完整的数据校验。判断用户输入能不能传给 int(),最稳妥的方式仍然是转换并处理可能出现的 ValueError。
十一、字符串格式化
把变量放进字符串时,通常使用 f-string。它从 Python 3.6 开始支持,写法是在字符串前加 f,然后把变量或表达式放入花括号:
python
name = "Ivan"
age = 20
message = f"姓名:{name},年龄:{age}"
print(message)
花括号中可以写表达式:
python
price = 19.9
count = 3
print(f"总价:{price * count}")
1. 控制小数位数
python
price = 19.956
print(f"{price:.2f}")
print(f"{price:.1f}")
输出结果为:
txt
19.96
20.0
2. 千位分隔与百分比
python
number = 1234567.89
rate = 0.856
print(f"{number:,.2f}")
print(f"{rate:.1%}")
输出结果为:
txt
1,234,567.89
85.6%
3. 对齐与宽度
< 表示左对齐,> 表示右对齐,^ 表示居中:
python
text = "Python"
print(f"|{text:<10}|")
print(f"|{text:>10}|")
print(f"|{text:^10}|")
输出结果为:
txt
|Python |
| Python|
| Python |
4. 日期格式
日期对象也可以放进 f-string 中格式化:
python
from datetime import datetime
now = datetime(2026, 8, 21, 10, 30)
print(f"{now:%Y-%m-%d %H:%M}")
输出结果为:
txt
2026-08-21 10:30
5. str.format()
旧一些的代码中经常能看到 format():
python
name = "Ivan"
score = 95.5
message = "{} 的成绩是 {:.1f} 分".format(name, score)
print(message)
它仍然可以正常使用,不过新代码在大多数情况下使用 f-string 更直观。%s、%d 这种百分号格式化也会出现在旧代码和日志配置中,能够看懂即可。

十二、字符串与字节
Python 中的 str 保存 Unicode 文本,bytes 保存字节数据。文本写入文件或者通过网络传输时,通常需要按照某种编码转换成字节。
1. 编码
encode() 把字符串转换成字节:
python
text = "你好,Python"
data = text.encode("utf-8")
print(data)
print(type(data))
2. 解码
decode() 把字节转换回字符串:
python
text = data.decode("utf-8")
print(text)
编码和解码必须使用相同或者兼容的字符编码。用错误编码解码,可能出现乱码,也可能引发 UnicodeDecodeError。
python
text = "你好"
data = text.encode("utf-8")
# 错误的解码方式
# result = data.decode("ascii")
UTF-8 中,一个中文字符通常占三个字节,所以字符数和字节数可能不同:
python
text = "你好"
print(len(text))
print(len(text.encode("utf-8")))
输出结果为:
txt
2
6

十三、综合示例:整理一条商品信息
下面接收一行商品数据,去掉多余空格,再拆出名称、单价和数量,最后计算总价:
python
raw_text = input("请输入商品信息,格式为 名称,单价,数量:")
parts = raw_text.strip().split(",")
if len(parts) != 3:
print("输入格式不正确")
else:
name = parts[0].strip()
price = float(parts[1].strip())
count = int(parts[2].strip())
total = price * count
print(f"商品:{name}")
print(f"单价:{price:.2f} 元")
print(f"数量:{count}")
print(f"总价:{total:.2f} 元")
输入:
txt
Python 入门书, 59.8, 2
输出结果为:
txt
商品:Python 入门书
单价:59.80 元
数量:2
总价:119.60 元
示例中的 if 和 else 属于条件判断。这里先看程序怎样把字符串清理、拆分和转换,条件判断会在下一章详细讲。
十四、常见错误
1. 索引超出范围
python
text = "Python"
print(text[6])
字符串长度为 6,最后一个有效索引是 5。
2. 忘记接收字符串方法的返回值
python
text = " Python "
text.strip()
print(repr(text))
strip() 没有修改原字符串。应该写成:
python
text = text.strip()
3. 把 strip() 当成删除完整前缀
python
url = "www.example.com"
result = url.strip("www.")
strip() 按字符集合删除两端内容。删除固定前缀应该使用:
python
result = url.removeprefix("www.")
4. 混淆 split() 与 join()
python
text = "Python,Java,Go"
items = text.split(",") # 字符串拆成列表
result = ",".join(items) # 列表连接成字符串
5. 在普通字符串中直接写 Windows 路径
python
path = "C:\new\test.txt"
其中的 \n 和 \t 会被当成转义字符。可以使用双反斜杠、原始字符串,或者后面会讲到的 pathlib。
6. 使用字节长度代替字符长度
python
text = "你好"
print(len(text))
print(len(text.encode("utf-8")))
前者是字符数量,后者是 UTF-8 编码后的字节数量。限制用户名长度时通常看字符数,限制网络报文或文件大小时才会考虑字节数。
十五、练习
练习一:取得文件名和扩展名
给定字符串 "archive.backup.zip",分别取得文件名 "archive.backup" 和扩展名 "zip"。可以先使用 rfind() 找到最后一个点的位置,再配合切片完成。
练习二:隐藏手机号码
输入一个 11 位手机号码,只显示前 3 位和后 4 位,中间使用四个星号代替。例如:
txt
138****5678
练习三:统计单词
给定一段英文文本,去掉两端空格并按照空白拆分,统计其中有多少个单词。
练习四:整理标签
输入字符串 " Python, 数据分析, Web开发 ",去掉每个标签两端的空格,再使用 " | " 连接成下面的形式:
txt
Python | 数据分析 | Web开发
练习五:检查文件类型
判断文件名是否以 .jpg、.jpeg、.png 或 .gif 结尾。检查时要忽略扩展名的大小写。
这一章把字符串中最常用的内容放在了一起。后面处理输入数据、文件内容和接口结果时,索引、切片、拆分、替换和格式化都会经常用到。