【Python入门】6.1数据容器--字符串(str)
Python 字符串完全指南(系统+详细)
字符串是 Python 中最常用的不可变序列类型,用于表示文本数据。本指南从基础到进阶,覆盖字符串的核心知识,包含语法、操作、方法、格式化、编码等内容,适合Python初学者系统学习。
一、字符串的定义与创建
字符串是由单个字符组成的有序集合,字符可以是字母、数字、符号、中文等 Unicode 字符。Python 中创建字符串的方式灵活多样,核心规则是用引号包裹。
1. 基本创建方式(3种引号)
- 单引号
' ':适合包含双引号的字符串(无需转义) - 双引号
" ":适合包含单引号的字符串(无需转义) - 三引号
''' '''或""" """:支持多行字符串、保留格式(如换行、缩进),也可作为注释(但非官方推荐注释方式)
# 1. 单引号
str1 = 'Hello Python'
str2 = 'He said: "Python is easy"' # 包含双引号,无需转义
# 2. 双引号
str3 = "Hello Python"
str4 = "I'm learning Python" # 包含单引号,无需转义
# 3. 三引号(多行字符串)
str5 = '''第一行
第二行
第三行''' # 保留换行符\n
str6 = """Python 字符串
支持 Unicode,比如中文、日文:こんにちは"""
# 4. 空字符串(长度为0)
empty_str = "" # 或 ''、''''''
print(len(empty_str)) # 输出:0
2. 转义字符(处理特殊字符)
当需要在字符串中包含无法直接输入的字符(如换行、制表符)或与引号冲突的字符时,使用 \ 作为转义符。
| 转义字符 | 含义 | 示例 | 输出结果 |
|---|---|---|---|
\n | 换行 | print("a\nb") | a b |
\t | 制表符(Tab,4个空格) | print("a\tb") | a b |
\\ | 输出反斜杠 \ | print("a\\b") | a\b |
\' | 输出单引号 ' | print('I\'m Tom') | I’m Tom |
\" | 输出双引号 " | print("He said \"Hi\"") | He said “Hi” |
\r | 回车(覆盖当前行) | print("abc\r123") | 123 |
\uXXXX | Unicode 字符(4位十六进制) | print("\u4e2d") | 中 |
原始字符串(禁用转义)
在字符串前加 r 或 R,表示原始字符串,\ 不再是转义符(常用于文件路径、正则表达式):
# 普通字符串(\n 被转义为换行)
print("C:\new\test.txt") # 输出混乱(\n 换行)
# 原始字符串(\ 不转义)
print(r"C:\new\test.txt") # 输出:C:\new\test.txt
print(R"He said: \"Hi\"") # 输出:He said: \"Hi\"(\ 保留)
3. Unicode 支持(多语言字符)
Python 3 的字符串默认是 Unicode 编码,可直接包含任意语言的字符,无需额外处理:
# 中文、日文、特殊符号均可直接使用
str_unicode = "中文 Python 🐍 日本語 한국어"
print(str_unicode) # 正常输出所有字符
print(len(str_unicode)) # 输出:15(每个 Unicode 字符算1个长度)
二、字符串的核心属性:不可变性
Python 字符串是不可变对象——创建后无法直接修改单个字符,只能通过「创建新字符串」来实现“修改”效果。
s = "hello"
# 错误:试图修改第0个字符(会报错 TypeError)
# s[0] = "H"
# 正确方式:通过拼接/切片创建新字符串
s_new = "H" + s[1:] # 拼接 + 切片
print(s_new) # 输出:Hello
# 原字符串并未改变
print(s) # 输出:hello
❌ 常见误区:试图通过索引赋值修改字符串,会直接抛出 TypeError。
三、字符串的访问:索引与切片
字符串是有序序列,每个字符都有唯一的索引(位置编号),可通过索引访问单个字符,通过切片获取子字符串。
1. 索引(访问单个字符)
- 正向索引:从左到右,起始为
0(第一个字符) - 反向索引:从右到左,起始为
-1(最后一个字符)
语法:字符串[索引值]
s = "Python"
# 字符串长度:len(s) = 6,正向索引 0~5,反向索引 -1~-6
print(s[0]) # 正向:第一个字符 → 'P'
print(s[3]) # 正向:第四个字符 → 'h'
print(s[-1]) # 反向:最后一个字符 → 'n'
print(s[-3]) # 反向:倒数第三个字符 → 'h'
# 错误:索引越界(超出 0~len(s)-1 范围)
# print(s[6]) # IndexError: string index out of range
# print(s[-7]) # IndexError: string index out of range
2. 切片(获取子字符串)
切片用于截取字符串的一部分,返回新字符串(不改变原字符串)。
语法:字符串[start:end:step]
start:起始索引(包含,默认0)end:结束索引(不包含,默认len(字符串))step:步长(每次跳过的字符数,默认1;step>0正向截取,step<0反向截取)
常见用法示例
s = "abcdefghij" # 索引 0-9(正向),-10~-1(反向)
# 1. 基础切片(start:end)
print(s[2:5]) # 从索引2到4(不包含5)→ 'cde'
print(s[0:3]) # 从开头到索引2 → 'abc'(等价于 s[:3])
print(s[7:]) # 从索引7到结尾 → 'hij'
print(s[:]) # 复制整个字符串 → 'abcdefghij'
# 2. 步长切片(start:end:step)
print(s[0:8:2]) # 步长2:0→2→4→6 → 'aceg'
print(s[::3]) # 从开头到结尾,步长3 → 'adgj'
print(s[::-1]) # 步长-1:反向截取(反转字符串)→ 'jihgfedcba'
print(s[8:3:-1]) # 反向从索引8到4 → 'jihgf'
# 3. 负数索引切片
print(s[-5:-2]) # 从倒数第5到倒数第3 → 'fgh'
print(s[-3:]) # 倒数3个字符 → 'hij'
✅ 切片的核心特点:
- 左闭右开(包含 start,不包含 end)
- 索引越界不报错(自动忽略超出范围的部分):
s[100:200]→''(空字符串) - 始终返回新字符串(原字符串不变)
四、字符串的基础操作(拼接、重复、判断等)
Python 提供了简洁的运算符,用于字符串的常见操作。
1. 拼接(+)
将两个或多个字符串合并为一个新字符串:
a = "Hello"
b = "Python"
c = a + " " + b # 拼接空格
print(c) # 输出:Hello Python
# 注意:只能拼接字符串,不能直接拼接其他类型(需先转换)
age = 20
# print("My age is " + age) # 错误:TypeError(字符串+整数)
print("My age is " + str(age)) # 正确:转换为字符串 → 'My age is 20'
2. 重复(*)
将字符串重复 n 次(n 为非负整数):
s = "ab"
print(s * 3) # 输出:ababab
print("-" * 10) # 输出:----------(常用作分隔线)
print(s * 0) # 输出:''(空字符串)
3. 成员判断(in / not in)
判断一个字符串是否是另一个字符串的子串(返回布尔值 True/False):
s = "Python is fun"
print("Python" in s) # True("Python" 是 s 的子串)
print("java" in s) # False
print("fun" not in s) # False
print("is" in s) # True
4. 长度计算(len())
用内置函数 len() 获取字符串的长度(每个 Unicode 字符算1个长度):
print(len("hello")) # 5
print(len("中文 Python")) # 8("中文"2个 + 空格1个 + "Python"6个)
print(len("")) # 0(空字符串长度)
5. 最大值/最小值(max() / min())
返回字符串中字符 Unicode 编码最大/最小的字符(仅对非空字符串有效):
s = "abc123"
print(max(s)) # 'c'(Unicode 编码:'c'>'b'>'a'>'3'>'2'>'1')
print(min(s)) # '1'
五、字符串的内置方法(核心重点)
Python 为字符串提供了大量内置方法(str.方法名()),用于字符串的修改、查找、替换、判断等操作。所有方法均返回新字符串/结果,不改变原字符串(因字符串不可变)。
1. 大小写转换
| 方法 | 功能 | 示例 | 输出 |
|---|---|---|---|
lower() | 全部转为小写 | "HELLO Python".lower() | ‘hello python’ |
upper() | 全部转为大写 | "hello Python".upper() | ‘HELLO PYTHON’ |
capitalize() | 首字母大写,其余小写 | "hello PYTHON".capitalize() | ‘Hello python’ |
title() | 每个单词首字母大写(分隔符:非字母) | "hello python 2024".title() | ‘Hello Python 2024’ |
swapcase() | 大小写反转 | "Hello Python".swapcase() | ‘hELLO pYTHON’ |
s = "PyThOn 编程"
print(s.lower()) # 'python 编程'
print(s.title()) # 'Python 编程'(中文不影响)
2. 去除空白字符
空白字符包括:空格 、制表符 \t、换行符 \n、回车符 \r 等。
| 方法 | 功能 | 示例 | 输出 |
|---|---|---|---|
strip() | 去除字符串两端的空白字符 | " \thello\n ".strip() | ‘hello’ |
lstrip() | 去除字符串左端的空白字符 | " \thello\n ".lstrip() | 'hello\n ’ |
rstrip() | 去除字符串右端的空白字符 | " \thello\n ".rstrip() | ’ \thello’ |
strip(chars) | 去除两端指定的字符(chars为字符串) | "###hello###".strip("#") | ‘hello’ |
# 去除两端的特定字符(如逗号、空格)
s = ", hello world! ,"
print(s.strip(", ")) # 输出:'hello world!'(去除逗号和空格)
3. 查找与替换
(1)查找子串(返回索引或 -1)
| 方法 | 功能 | 示例 | 输出 |
|---|---|---|---|
find(sub) | 从左查找子串sub,返回第一个匹配的起始索引;无匹配返回 -1 | "abcabc".find("ab") | 0 |
rfind(sub) | 从右查找子串sub,返回第一个匹配的起始索引;无匹配返回 -1 | "abcabc".rfind("ab") | 3 |
index(sub) | 与find()一致,但无匹配时抛出 ValueError | "abc".index("d") | 报错 |
rindex(sub) | 与rfind()一致,但无匹配时抛出 ValueError | "abc".rindex("d") | 报错 |
count(sub) | 统计子串sub出现的次数(无匹配返回0) | "abcabcab".count("ab") | 3 |
s = "Python is a good language, Python is easy"
print(s.find("Python")) # 0(第一个Python的起始索引)
print(s.rfind("Python")) # 28(最后一个Python的起始索引)
print(s.count("is")) # 2("is"出现2次)
print(s.find("Java")) # -1(无匹配)
(2)替换子串(返回新字符串)
| 方法 | 功能 | 示例 | 输出 |
|---|---|---|---|
replace(old, new) | 将所有old子串替换为new | "abab".replace("a", "x") | ‘xbxb’ |
replace(old, new, count) | 替换前count个old子串 | "ababab".replace("a", "x", 2) | ‘xbxbab’ |
s = "I love Python, Python is great"
s_new1 = s.replace("Python", "Java") # 替换所有Python
print(s_new1) # 输出:'I love Java, Java is great'
s_new2 = s.replace("Python", "Java", 1) # 只替换第一个Python
print(s_new2) # 输出:'I love Java, Python is great'
4. 分割与连接
(1)分割字符串(返回列表)
将字符串按指定分隔符拆分,返回列表(列表元素为子字符串)。
| 方法 | 功能 | 示例 | 输出 |
|---|---|---|---|
split(sep) | 按sep分割(默认sep为空白字符),忽略首尾空白 | "a b c".split() | [‘a’,‘b’,‘c’] |
split(sep, maxsplit) | 按sep分割,最多分割maxsplit次 | "a,b,c,d".split(",", 2) | [‘a’,‘b’,‘c,d’] |
rsplit(sep, maxsplit) | 从右向左分割,最多maxsplit次 | "a,b,c,d".rsplit(",", 2) | [‘a,b’,‘c’,‘d’] |
splitlines() | 按换行符(\n、\r\n等)分割,默认不保留换行 | "a\nb\r\nc".splitlines() | [‘a’,‘b’,‘c’] |
splitlines(keepends=True) | 保留换行符 | "a\nb".splitlines(True) | [‘a\n’,‘b’] |
# 1. 按逗号分割
s1 = "apple,banana,orange"
print(s1.split(",")) # 输出:['apple', 'banana', 'orange']
# 2. 按空格分割(默认)
s2 = "hello world python" # 多个空格视为一个分隔符
print(s2.split()) # 输出:['hello', 'world', 'python']
# 3. 限制分割次数
s3 = "a-b-c-d-e"
print(s3.split("-", 3)) # 分割3次 → ['a', 'b', 'c', 'd-e']
# 4. 按换行分割
s4 = "第一行\n第二行\r\n第三行"
print(s4.splitlines()) # 输出:['第一行', '第二行', '第三行']
(2)连接列表(返回字符串)
用字符串作为分隔符,将列表中的元素连接为一个新字符串(列表元素必须是字符串类型)。
方法:分隔符.join(列表)
# 1. 用逗号连接
fruits = ["apple", "banana", "orange"]
print(", ".join(fruits)) # 输出:'apple, banana, orange'
# 2. 用空字符串连接(拼接列表元素)
chars = ["P", "y", "t", "h", "o", "n"]
print("".join(chars)) # 输出:'Python'
# 3. 用换行符连接(多行字符串)
lines = ["第一行", "第二行", "第三行"]
print("\n".join(lines)) # 输出:第一行\n第二行\n第三行(换行显示)
# 错误:列表元素包含非字符串(需先转换)
nums = [1, 2, 3]
# print("-".join(nums)) # 报错:TypeError
print("-".join(str(num) for num in nums)) # 正确 → '1-2-3'
5. 判断字符串类型(返回布尔值)
这类方法用于判断字符串是否满足特定条件(如是否全是字母、是否是数字等),常用于数据校验。
| 方法 | 功能 | 示例 | 输出 |
|---|---|---|---|
isalpha() | 是否全是字母(含中文等Unicode字母) | "Python编程".isalpha() | True |
isdigit() | 是否全是数字(0-9,不含小数点) | "12345".isdigit() | True |
isnumeric() | 是否全是数值(含数字、汉字数字、罗马数字) | "123四Ⅴ".isnumeric() | True |
isalnum() | 是否全是字母或数字(含Unicode) | "Python123".isalnum() | True |
isspace() | 是否全是空白字符(空格、\t、\n等) | " \t\n".isspace() | True |
islower() | 是否全是小写字母 | "hello".islower() | True |
isupper() | 是否全是大写字母 | "HELLO".isupper() | True |
istitle() | 是否是标题格式(每个单词首字母大写) | "Hello World".istitle() | True |
startswith(prefix) | 是否以prefix开头(可加start/end参数) | "Python".startswith("Py") | True |
endswith(suffix) | 是否以suffix结尾(可加start/end参数) | "Python".endswith("on") | True |
# 数据校验示例:判断输入是否为纯数字
user_input = input("请输入年龄:")
if user_input.isdigit():
age = int(user_input)
print(f"年龄:{age}")
else:
print("输入错误!请输入数字。")
# startswith/endswith 加范围参数
s = "abcdef"
print(s.startswith("bc", 1, 4)) # 从索引1到3(不包含4)是否以"bc"开头 → True
print(s.endswith("de", 2, 5)) # 从索引2到4是否以"de"结尾 → True
六、字符串格式化(拼接变量的优雅方式)
字符串格式化用于将变量嵌入字符串中,比 + 拼接更灵活、可读性更强。Python 支持3种主流格式化方式,推荐优先使用 f-string(Python3.6+)。
1. f-string(格式化字符串字面值,推荐)
语法:在字符串前加 f 或 F,变量/表达式用 {} 包裹,直接嵌入字符串。
基本用法
name = "Tom"
age = 20
height = 1.75
# 1. 嵌入变量
print(f"我叫{name},今年{age}岁,身高{height}米。")
# 输出:我叫Tom,今年20岁,身高1.75米。
# 2. 嵌入表达式(直接计算)
print(f"明年我{age+1}岁,身高的2倍是{height*2}米。")
# 输出:明年我21岁,身高的2倍是3.5米。
# 3. 嵌入函数调用
print(f"名字大写:{name.upper()},名字长度:{len(name)}。")
# 输出:名字大写:TOM,名字长度:3。
格式控制(保留小数、对齐等)
在 {变量:格式说明} 中添加格式符,控制输出格式:
# 1. 保留小数(:.nf → 保留n位小数)
pi = 3.1415926
print(f"π ≈ {pi:.2f}") # 保留2位 → 3.14
print(f"π ≈ {pi:.4f}") # 保留4位 → 3.1416
# 2. 数字补零/对齐(:n>m → 右对齐,不足m位补n;:n<m → 左对齐)
num = 123
print(f"右对齐(补0,5位):{num:0>5}") # 00123
print(f"左对齐(补-,5位):{num:-<5}") # 123--
# 3. 千位分隔符(:,)
salary = 1234567
print(f"工资:{salary:,} 元") # 1,234,567 元
# 4. 百分比格式(:.n% → 保留n位小数,转为百分比)
rate = 0.789
print(f"通过率:{rate:.1%}") # 78.9%
2. str.format() 方法(兼容Python2/3)
语法:用 {} 作为占位符,通过 format() 传入变量/值,按顺序或关键字匹配。
# 1. 按顺序匹配
print("我叫{},今年{}岁。".format("Tom", 20)) # 我叫Tom,今年20岁。
# 2. 按索引匹配(可重复使用)
print("第1个:{0},第2个:{1},再第1个:{0}".format("a", "b")) # 第1个:a,第2个:b,再第1个:a
# 3. 按关键字匹配
print("我叫{name},身高{height}米。".format(name="Tom", height=1.75)) # 我叫Tom,身高1.75米。
# 4. 格式控制(与f-string一致)
pi = 3.1415926
print("π ≈ {:.2f}".format(pi)) # 3.14
print("工资:{:,} 元".format(1234567)) # 1,234,567 元
3. % 格式化(老式方法,不推荐)
语法:类似C语言的 printf,用 % 作为占位符,后续跟变量元组。
| 占位符 | 含义 | 示例 | 输出 |
|---|---|---|---|
%s | 字符串 | "名字:%s" % “Tom” | 名字:Tom |
%d | 整数 | "年龄:%d" % 20 | 年龄:20 |
%f | 浮点数 | "身高:%.2f" % 1.75 | 身高:1.75 |
%x | 十六进制数 | "十六进制:%x" % 255 | 十六进制:ff |
name = "Tom"
age = 20
height = 1.75
print("我叫%s,今年%d岁,身高%.2f米。" % (name, age, height))
# 输出:我叫Tom,今年20岁,身高1.75米。
✅ 推荐优先级:f-string > str.format() > % 格式化(f-string 最简洁、高效)。
七、字符串编码与解码(处理文件/网络数据)
字符串在计算机中存储和传输时,需要将 Unicode 字符转换为字节序列(编码);读取时再将字节序列转回 Unicode 字符(解码)。
1. 编码(str → bytes):encode()
语法:字符串.encode(encoding="utf-8", errors="strict")
encoding:编码格式(默认utf-8,常用还有gbk、gb2312)errors:编码错误处理方式(strict报错、ignore忽略、replace替换为?)
s = "中文 Python"
# 1. UTF-8编码(推荐,兼容所有语言)
bytes_utf8 = s.encode("utf-8")
print(bytes_utf8) # 输出:b'\xe4\xb8\xad\xe6\x96\x87 Python'(b开头表示bytes类型)
# 2. GBK编码(仅支持中文,字节数更少)
bytes_gbk = s.encode("gbk")
print(bytes_gbk) # 输出:b'\xd6\xd0\xce\xc4 Python'
# 3. 处理编码错误(如用gbk编码日文)
s2 = "中文 こんにちは"
# bytes_gbk_error = s2.encode("gbk") # 报错:UnicodeEncodeError
bytes_gbk_ignore = s2.encode("gbk", errors="ignore") # 忽略无法编码的字符
print(bytes_gbk_ignore) # 输出:b'\xd6\xd0\xce\xc4 '
2. 解码(bytes → str):decode()
语法:字节序列.decode(encoding="utf-8", errors="strict")
- 解码时的
encoding必须与编码时一致,否则会出现乱码或报错。
# 1. UTF-8解码(对应上面的UTF-8编码)
bytes_utf8 = b'\xe4\xb8\xad\xe6\x96\x87 Python'
s_utf8 = bytes_utf8.decode("utf-8")
print(s_utf8) # 输出:中文 Python
# 2. GBK解码(对应上面的GBK编码)
bytes_gbk = b'\xd6\xd0\xce\xc4 Python'
s_gbk = bytes_gbk.decode("gbk")
print(s_gbk) # 输出:中文 Python
# 3. 错误解码(用utf-8解码gbk字节序列 → 乱码)
s_wrong = bytes_gbk.decode("utf-8")
print(s_wrong) # 输出:�й� Python(乱码)
✅ 实际应用场景:
- 读取文件时指定编码(
open("file.txt", "r", encoding="utf-8")) - 网络请求/响应数据的编码转换(如 requests 库的
response.encoding = "utf-8")
八、字符串高级用法
1. 正则表达式(复杂字符串处理)
当需要实现模糊匹配、复杂查找/替换(如提取手机号、邮箱、替换所有符合规则的子串)时,使用 re 模块(正则表达式)。
简单示例:提取字符串中的数字
import re
s = "我的手机号是13812345678,年龄25岁,工资12345.67元"
# 1. 提取所有数字(包括整数和小数)
numbers = re.findall(r"\d+\.?\d*", s)
print(numbers) # 输出:['13812345678', '25', '12345.67']
# 2. 提取手机号(11位数字)
phone = re.findall(r"1[3-9]\d{9}", s)
print(phone) # 输出:['13812345678']
# 3. 替换所有数字为"*"
s_new = re.sub(r"\d", "*", s)
print(s_new) # 输出:我的手机号是***********,年龄**岁,工资*****.**元
2. 高效字符串操作技巧
-
避免频繁拼接:大量字符串拼接时,用
list.append()收集后再join(),比+高效(+每次都会创建新字符串):# 低效(频繁创建新字符串) s = "" for i in range(1000): s += str(i) # 高效(仅创建1次最终字符串) lst = [] for i in range(1000): lst.append(str(i)) s = "".join(lst) -
字符串常量池:Python 会缓存短字符串(通常长度≤20),重复使用时直接引用,而非创建新对象:
a = "hello" b = "hello" print(a is b) # 输出:True(同一对象) c = "hello world" * 10 # 长字符串,不缓存 d = "hello world" * 10 print(c is d) # 输出:False(不同对象)
九、常见问题与注意事项
- 不可变性误区:试图通过索引修改字符串会报错,需用拼接/切片创建新字符串。
- 转义字符混淆:路径、正则表达式中尽量用原始字符串(
r""),避免\转义问题。 - 编码乱码:文件读取/网络传输时,确保编码格式一致(优先用
utf-8)。 - 格式化类型匹配:
%d只能接收整数,%f接收浮点数,误用会报错(如"%d" % 3.14报错,需用"%d" % int(3.14))。 - 中文长度计算:
len("中文")输出2(每个中文是1个Unicode字符),而非字节数("中文".encode("utf-8")是6个字节)。
总结
字符串是 Python 中最基础且核心的数据类型,掌握以下重点即可应对90%的场景:
- 字符串的创建(3种引号、转义字符、原始字符串);
- 索引与切片(访问和截取字符串);
- 核心方法(大小写、去空白、查找替换、分割连接、类型判断);
- 格式化(优先用 f-string);
- 编码解码(处理文件/网络数据)。
建议多通过实际案例练习(如文本处理、数据清洗),加深对字符串方法和特性的理解!
更多推荐


所有评论(0)