字符串的转义符 (Escape Characters)
在字符串中,反斜杠 \ 用来引入特殊的字符序列,这些序列被称为转义符。使用转义符是因为在 Python 字符串中,有些字符具有特殊含义(比如换行、制表符、引号等),直接使用可能会引起语法错误或无法达到预期效果。
比如:字符串表示常常用单引号 ' 或双引号 " 包围,如果字符串本身包含这些引号,就需要使用转义符。
常见的转义符包括:
| 转义符 | 含义 | 示例说明 |
|---|
\\ | 反斜杠本身 | "C:\\Users\\name" → C:\Users\name |
\' | 单引号 | 'It\'s OK' → It's OK |
\" | 双引号 | "He said \"Hi\"" → He said "Hi" |
\n | 换行符 | "Hello\nWorld" → 两行输出 |
\t | 制表符(Tab) | "Name:\tAlice" → 名字后有空格对齐 |
\r | 回车(Carriage Return) | 通常与 \n 配合用于 Windows 换行 |
\b | 退格(Backspace) | "a\bc" → 显示为 c(较少用) |
\f | 换页符(Form Feed) | 打印时换页(现代很少用) |
\v | 垂直制表符 | 控制打印机垂直间距(罕见) |
\0 | 空字符(Null) | 表示 ASCII 0(极少用) |
💡 注意:如果在字符串中写了无效的转义序列(如 \z),Python 会发出 SyntaxWarning(3.12+ 版本会报错),所以建议只使用标准转义符。
转义符使用示例
# 示例 1:包含单引号和双引号的字符串
s1 = 'It\'s a "great" day!'
print(s1) # 输出: It's a "great" day!
# 示例 2:换行和制表
s2 = "第一行\n\t第二行(缩进)\n第三行"
print(s2)
# 输出:
# 第一行
# 第二行(缩进)
# 第三行
# 示例 3:文件路径中的反斜杠(需转义)
path = "C:\\Users\\Alice\\Documents"
print(path) # 输出: C:\Users\Alice\Documents
原始字符串(Raw String)
为了避免频繁使用反斜杠转义,Python 提供了原始字符串(raw string)。在字符串前加 r 或 R,即可让字符串中的所有反斜杠都被视为普通字符,不再具有转义功能。
# 使用原始字符串表示文件路径
raw_path = r"C:\Users\Alice\Documents"
print(raw_path) # 输出: C:\Users\Alice\Documents
# 原始字符串常用于正则表达式
import re
pattern = r"\d+\.\d+" # 匹配小数,如 3.14
text = "The value is 3.14 and 2.71."
matches = re.findall(pattern, text)
print(matches) # 输出: ['3.14', '2.71']
⚠️ 注意:原始字符串不能以奇数个反斜杠结尾,例如 r"hello\" 是非法的,因为最后一个 \ 会试图转义后面的引号,但原始字符串不允许转义。如果需要结尾反斜杠,可改用普通字符串或拼接:r"C:\folder" + "\\"。
字符串的格式化输出
Python 有多种格式化方式(如 % 操作符, .format()),但从 Python 3.6 开始,f-string (Formatted String Literals) 成为了最推荐、最高效的方式。所以这里就不多说其他方式了。
f-string 的详细用法:
语法:在字符串引号前加上 f 或 F,在大括号 {} 中直接填入变量或表达式。
基础变量与表达式
name = "Python"
age = 30
# 直接引用变量
print(f"I am learning {name}, it is {age} years old.")
# 支持表达式
print(f"Next year, it will be {age + 1} years old.")
# 支持函数调用
print(f"Name in upper case: {name.upper()}")
浮点数精度控制
使用 :.nf 控制小数点位数。
pi = 3.1415926
print(f"Pi is approx {pi:.2f}") # 保留2位小数 -> 3.14
宽度与对齐
格式:{value : 填充字符 对齐方式 宽度}
text = "Hi"
# 宽度10,默认右对齐(字符串通常默认左对齐,但在f-string指定宽度后需注意)
print(f"|{text:10}|") # 输出: |Hi |
# 宽度10,右对齐
print(f"|{text:>10}|") # 输出: | Hi|
# 宽度10,居中对齐,使用 * 填充
print(f"|{text:*^10}|") # 输出: |****Hi****|
数字格式化 (千分位、进制)
money = 1234567890
print(f"Total: {money:,}") # 千分位分隔 -> 1,234,567,890
num = 255
print(f"Binary: {num:b}") # 二进制 -> 11111111
print(f"Hex: {num:x}") # 十六进制 -> ff
调试模式 (Python 3.8+)
在变量后加 =,可以同时输出“变量名=变量值”,非常适合调试。
x = 10
y = 20
print(f"{x=}, {y=}, {x+y=}")
# 输出: x=10, y=20, x+y=30
字符串的索引和切片
字符串是有序序列,每个字符都有确定的位置。
索引 (Indexing)
- 正向索引:从 0 开始,从左向右递增。
- 负向索引:从 -1 开始,从右向左递减(-1 代表最后一个字符)。
s = "PYTHON"
# 0 1 2 3 4 5 (正向)
# P Y T H O N
# -6 -5 -4 -3 -2 -1 (负向)
print(s[0]) # P
print(s[5]) # N
print(s[-1]) # N (倒数第一个)
print(s[-2]) # O (倒数第二个)
切片 (Slicing)
语法:[start : stop : step]
start: 起始索引(包含)。默认为 0。stop: 结束索引(不包含)。默认为字符串长度。step: 步长。默认为 1,如果设置为2,则每两个字符取一个。
重要规则:
- 顾头不顾尾:取值范围是
[start, stop)。
假设现在有字符串 s = "Hello World",则 s[0:5] 会取索引取得 0 到 4 的字符,即 "Hello",不包含索引 5 的字符(空格)。所以被称为“顾头不顾尾”。 步长方向:
- 若
step 为正,从左往右取。 - 若
step 为负,从右往左取(实现反序的关键)。
s = "Hello World"
# 1. 基础切片
print(s[0:5]) # 取索引0到4 -> "Hello"
print(s[:5]) # start省略,默认从头 -> "Hello"
print(s[6:]) # stop省略,默认到尾 -> "World"
print(s[:]) # 完整拷贝 -> "Hello World"
# 2. 带步长的切片
print(s[::2]) # 每隔一个字符取一个 -> "HloWrd"
# 3. 负数索引切片
print(s[-5:-1]) # 取倒数第5个到倒数第2个 -> "Worl" (不包含-1对应的d)
# 4. 字符串反转 (面试常考)
print(s[::-1]) # 步长为负,从后往前取 -> "dlroW olleH"
字符串的常见操作符
除了方法外,Python 提供了很多操作符来处理字符串。
| 操作符 | 描述 | 示例 |
|---|
+ | 字符串拼接 | "Hi" + "!" -> "Hi!" |
* | 重复输出 | "A" * 3 -> "AAA" |
in | 成员判断(存在) | "a" in "abc" -> True |
not in | 成员判断(不存在) | "z" not in "abc" -> True |
== | 判断内容是否相等 | "a" == "a" -> True |
> / < | 按字典序(ASCII码)比较 | "a" < "b" -> True |
特别说明:
+=:虽然看起来像是在原字符串上修改,但因为字符串是不可变的,实际上 s += "a" 是创建了一个新字符串并重新赋值给变量 s。
s1 = "Hello"
s2 = "World"
# 拼接
print(s1 + " " + s2) # "Hello World"
# 重复
print("-" * 20) # 打印分割线: --------------------
# 成员检测
text = "Python is cool"
if "cool" in text:
print("Found it!")
# 比较
print("apple" < "banana") # True (a 在 b 前面)
字符串的常见内置方法
| 方法 | 功能简述 |
|---|
str.capitalize() | 首字母大写,其余小写 |
str.casefold() | 返回更激进的小写形式(用于无大小写比较) |
str.center(width[, fillchar]) | 居中对齐,用指定字符填充 |
str.count(sub[, start[, end]]) | 统计子串出现次数 |
str.encode([encoding[, errors]]) | 编码为 bytes |
str.endswith(suffix[, start[, end]]) | 判断是否以某后缀结尾 |
str.expandtabs([tabsize]) | 将 \t 替换为空格 |
str.find(sub[, start[, end]]) | 查找子串首次出现位置(未找到返回 -1) |
str.rfind(sub[, start[, end]]) | 从右向左查找子串 |
str.index(sub[, start[, end]]) | 类似 find,但未找到会抛出异常 |
str.rindex(sub[, start[, end]]) | 从右向左查找,未找到抛异常 |
str.isalnum() | 是否只包含字母和数字 |
str.isalpha() | 是否只包含字母 |
str.isascii() | 是否所有字符都是 ASCII |
str.isdecimal() | 是否只包含十进制数字(如 '0'–'9') |
str.isdigit() | 是否只包含数字(包括 Unicode 数字) |
str.isnumeric() | 是否表示数值(包括分数、罗马数字等) |
str.islower() | 是否全为小写 |
str.isupper() | 是否全为大写 |
str.istitle() | 是否为标题格式(每个单词首字母大写) |
str.isspace() | 是否只包含空白字符(空格、\n、\t 等) |
str.join(iterable) | 用当前字符串连接可迭代对象中的元素 |
str.ljust(width[, fillchar]) | 左对齐,右侧填充 |
str.rjust(width[, fillchar]) | 右对齐,左侧填充 |
str.lower() | 转为小写 |
str.upper() | 转为大写 |
str.title() | 每个单词首字母大写 |
str.swapcase() | 大小写互换 |
str.lstrip([chars]) | 去除左侧指定字符(默认空白) |
str.rstrip([chars]) | 去除右侧指定字符 |
str.strip([chars]) | 去除两侧指定字符 |
str.partition(sep) | 从左分割为三元组(前、分隔符、后) |
str.rpartition(sep) | 从右分割为三元组 |
str.replace(old, new[, count]) | 替换子串 |
str.split([sep[, maxsplit]]) | 按分隔符分割为列表 |
str.rsplit([sep[, maxsplit]]) | 从右开始分割 |
str.splitlines([keepends]) | 按行分割(\n, \r\n 等) |
str.startswith(prefix[, start[, end]]) | 判断是否以某前缀开头 |
str.zfill(width) | 在左侧补零至指定宽度 |
💡 所有方法均不改变原字符串,而是返回新对象。
1. capitalize()
将字符串首字母大写,其余转为小写。
s = "hello WORLD"
print(s.capitalize()) # 输出: Hello world
2. casefold()
比 lower() 更彻底地转换为小写,适用于国际化比较。
s = "ß" # 德语 sharp s
print(s.lower()) # 'ß'
print(s.casefold()) # 'ss'
3. center(width, fillchar=' ')
居中对齐,总长度为 width,不足部分用 fillchar 填充。
s = "Python"
print(s.center(10, '*')) # 输出: **Python**
4. count(sub, start=0, end=len(s))
统计子串 sub 出现的次数。
s = "banana"
print(s.count('a')) # 3
print(s.count('na', 2)) # 2(从索引2开始)
5. encode(encoding='utf-8', errors='strict')
将字符串编码为 bytes。
s = "你好"
b = s.encode('utf-8')
print(b) # b'\xe4\xbd\xa0\xe5\xa5\xbd'
6. endswith(suffix, start=0, end=len(s))
判断是否以 suffix 结尾(支持元组)。
filename = "script.py"
print(filename.endswith('.py')) # True
print(filename.endswith(('.py', '.js'))) # True
7. expandtabs(tabsize=8)
将 \t 替换为指定数量的空格。
s = "a\tb"
print(s.expandtabs(4)) # "a b"(a 后跟 3 个空格)
8. find(sub, start=0, end=len(s))
返回子串首次出现的索引,未找到返回 -1。
s = "hello"
print(s.find('l')) # 2
print(s.find('x')) # -1
9. rfind(sub, ...) / index(sub, ...) / rindex(sub, ...)
rfind: 从右往左找,返回最右匹配位置index: 同 find,但找不到时抛出 ValueErrorrindex: 同 rfind,但找不到时报错
s = "hello"
print(s.rfind('l')) # 3
print(s.index('e')) # 1
# print(s.index('x')) # 报错!
10. is...() 系列判断方法
返回 True 或 False,常用于输入验证。
print("abc".isalpha()) # True
print("abc123".isalnum()) # True
print("123".isdigit()) # True
print("⅕".isnumeric()) # True(分数)
print("Hello".istitle()) # True
print(" \t\n".isspace()) # True
区别:
isdecimal():仅限 0–9(最严格)isdigit():包括上标数字(如²)isnumeric():还包括中文数字、罗马数字等
11. join(iterable)
用当前字符串连接可迭代对象中的字符串。
words = ['Python', 'is', 'fun']
print(' '.join(words)) # "Python is fun"
print('-'.join('abc')) # "a-b-c"
⚠️ 可迭代对象中的元素必须是字符串,否则报错。
12. ljust(width, fillchar) / rjust(width, fillchar)
左对齐 / 右对齐填充。
s = "OK"
print(s.ljust(5, '.')) # "OK..."
print(s.rjust(5, '.')) # "...OK"
13. lower() / upper() / title() / swapcase()
大小写转换。
s = "Hello World"
print(s.lower()) # "hello world"
print(s.upper()) # "HELLO WORLD"
print(s.title()) # "Hello World"
print(s.swapcase()) # "hELLO wORLD"
14. strip() / lstrip() / rstrip()
去除首尾指定字符(默认为空白字符)。
s = " \t hello \n "
print(s.strip()) # "hello"
print("...hello...".strip('.')) # "hello"
15. partition(sep) / rpartition(sep)
按第一个/最后一个分隔符分割为三部分。
s = "name=value=extra"
print(s.partition('=')) # ('name', '=', 'value=extra')
print(s.rpartition('=')) # ('name=value', '=', 'extra')
16. replace(old, new, count=-1)
替换子串,count 控制替换次数。
s = "apple apple"
print(s.replace("apple", "orange")) # "orange orange"
print(s.replace("apple", "orange", 1)) # "orange apple"
17. split(sep=None, maxsplit=-1) / rsplit(...)
按分隔符分割为列表。若 sep=None,按任意空白分割。
s = "a,b,c"
print(s.split(',')) # ['a', 'b', 'c']
print("a b\n c".split()) # ['a', 'b', 'c']
s = "a.b.c.d"
print(s.rsplit('.', 1)) # ['a.b.c', 'd'](从右切一次)
18. splitlines(keepends=False)
按行分割(识别 \n, \r\n, \r 等)。
s = "Line1\nLine2\r\nLine3"
print(s.splitlines()) # ['Line1', 'Line2', 'Line3']
print(s.splitlines(True)) # 保留换行符
19. startswith(prefix, start=0, end=len(s))
判断是否以某前缀开头(支持元组)。
url = "https://example.com"
print(url.startswith("http")) # True
print(url.startswith(("http", "ftp"))) # True
20. zfill(width)
在左侧补零,常用于数字字符串对齐。
print("42".zfill(5)) # "00042"
print("-42".zfill(5)) # "-0042"(负号保留在最左)