字符串是 Python 中使用最频繁的数据类型之一。无论是从用户获取输入、读写文件、处理网络数据,还是生成报告,字符串操作无处不在。Python 的字符串处理能力非常强大,掌握好字符串操作能让你在处理文本时事半功倍。

字符串基础

创建字符串

# 四种创建方式
s1 = '单引号字符串'
s2 = "双引号字符串"
s3 = '''三单引号
支持换行'''
s4 = """三双引号
也支持换行"""

print(s1)  # 单引号字符串
print(s2)  # 双引号字符串
print(s3)  # 三单引号\n支持换行

单引号 vs 双引号

两种方式完全等价,选择标准是方便性:

# 字符串本身包含单引号时,用双引号更省事
msg1 = "It's a beautiful day"  # 不用转义
msg2 = 'It\'s a beautiful day' # 需要转义

# 字符串本身包含双引号时,用单引号更省事
msg3 = '他说:"你好"'
msg4 = "他说:\"你好\""

字符串索引与切片

索引

Python 字符串支持正索引(从 0 开始)和负索引(从 -1 开始):

text = "Python"

# 正索引(从 0 到 length-1)
print(text[0])  # P
print(text[1])  # y
print(text[5])  # n

# 负索引(从 -1 到 -length)
print(text[-1]) # n(最后一个字符)
print(text[-2]) # o(倒数第二个)
print(text[-6]) # P(第一个字符)

# 索引越界
# print(text[100])  # IndexError: string index out of range

切片(Slicing)

切片是 Python 最强大的特性之一,语法为 [start:stop:step]

text = "Hello, Python!"

# 基本切片 [start:stop](不包含 stop)
print(text[0:5])    # Hello(索引 0~4)
print(text[7:13])   # Python(索引 7~12)
print(text[:5])     # Hello(省略 start,从开头开始)
print(text[7:])     # Python!(省略 stop,直到结尾)
print(text[:])      # Hello, Python!(复制整个字符串)

# 步长切片 [start:stop:step]
print(text[::2])    # Hlo yhn(每隔一个字符取一个)
print(text[1::2])   # el,Pto!(从索引1开始,每隔一个)

# 负步长(反向)
print(text[::-1])   # !nohtyP ,olleH(反转字符串)

# 切片不会索引越界
print("Hello"[0:100])  # Hello(不会报错)
print("Hello"[100:200]) # (空字符串)

切片技巧汇总

s = "Python编程"

# 常用切片模式
s[:3]        # "Pyt"         前三个字符
s[3:]        # "hon编程"      从索引3到结尾
s[-3:]       # "编程"         最后三个字符
s[:-3]       # "Python"      去掉最后三个字符
s[::2]       # "Pto编"       偶数位字符
s[1::2]      # "yh程"        奇数位字符
s[::-1]      # "程编nohtyP"  反转

字符串方法

Python 的字符串类型提供了极其丰富的方法。

大小写转换

text = "Hello, Python!"

print(text.upper())          # HELLO, PYTHON!(全部大写)
print(text.lower())          # hello, python!(全部小写)
print(text.title())          # Hello, Python!(每个单词首字母大写)
print(text.capitalize())     # Hello, python!(首字母大写,其余小写)
print(text.swapcase())       # hELLO, pYTHON!(大小写互换)

# 实际应用:用户输入标准化
user_input = "  Admin  "
if user_input.strip().lower() == "admin":
    print("验证通过")

查找与判断

text = "Hello, Python! Python is great."

# find() - 查找子串位置(找不到返回 -1)
print(text.find("Python"))       # 7(第一次出现的位置)
print(text.find("Python", 10))   # 15(从索引10开始找)
print(text.find("Java"))         # -1(找不到)

# index() - 类似 find(),但找不到会报错
print(text.index("Python"))      # 7

# rfind() - 从右侧开始查找
print(text.rfind("Python"))      # 15(最后一次出现的位置)

# count() - 统计出现次数
print(text.count("Python"))      # 2
print(text.count("o"))           # 3

# startswith() / endswith()
print(text.startswith("Hello"))  # True
print(text.endswith("great."))   # True

判断类方法

# isalpha() - 是否全是字母
print("Hello".isalpha())     # True
print("Hello123".isalpha())  # False
print("你好".isalpha())      # True(中文字符也算字母)

# isdigit() - 是否全是数字
print("12345".isdigit())     # True
print("12.34".isdigit())     # False(小数点不是数字)

# isnumeric() - 更广泛的数字判断
print("123".isnumeric())     # True
print("一二三".isnumeric())  # True(中文数字)

# isalnum() - 是否只有字母或数字
print("Hello123".isalnum())  # True

# isspace() - 是否全是空白字符
print("   \t\n".isspace())   # True

# islower() / isupper()
print("hello".islower())     # True
print("HELLO".isupper())     # True

分割与拼接

# split() - 分割字符串
text = "apple,banana,orange"
print(text.split(","))       # ['apple', 'banana', 'orange']

text = "Python is awesome"
print(text.split())          # ['Python', 'is', 'awesome'](默认按空白分割)

# 限制分割次数
print(text.split(" ", 1))    # ['Python', 'is awesome']

# splitlines() - 按换行分割
text = "第一行\n第二行\n第三行"
print(text.splitlines())     # ['第一行', '第二行', '第三行']

# join() - 拼接字符串(split 的反操作)
fruits = ["apple", "banana", "orange"]
print(", ".join(fruits))     # apple, banana, orange
print("".join(fruits))       # applebananaorange

替换与清理

# replace() - 替换子串
text = "我喜欢猫,猫很可爱"
print(text.replace("猫", "狗"))       # 我喜欢狗,狗很可爱
print(text.replace("猫", "狗", 1))    # 我喜欢狗,猫很可爱(只替换1次)

# strip() - 去除两端空白
text = "  Hello, World!  \n"
print(repr(text.strip()))         # 'Hello, World!'
print(repr(text.lstrip()))        # 'Hello, World!  \n'(只去左侧)
print(repr(text.rstrip()))        # '  Hello, World!'(只去右侧)

# strip() 可以指定要去除的字符
text = "***Hello***"
print(text.strip("*"))            # Hello

# removeprefix() / removesuffix()(Python 3.9+)
text = "https://example.com"
print(text.removeprefix("https://"))  # example.com
print(text.removesuffix(".com"))      # https://example

填充与对齐

# center() - 居中
print("Python".center(20))        #       Python       
print("Python".center(20, "-"))   # -------Python-------

# ljust() / rjust() - 左/右对齐
print("Python".ljust(10, "."))    # Python....
print("Python".rjust(10, "."))    # ....Python

# zfill() - 用 0 填充(左侧)
print("42".zfill(5))              # 00042
print("-42".zfill(5))             # -0042

# 实际应用:格式化表格输出
headers = ["姓名", "年龄", "城市"]
data = [
    ["张三", 25, "北京"],
    ["李四", 30, "上海"],
    ["王五", 22, "广州"]
]

for row in [headers] + data:
    print(f"{row[0].ljust(6)} {str(row[1]).center(6)} {row[2].ljust(6)}")

字符串格式化

f-string(Python 3.6+,推荐)

f-string 是目前最推荐、最强大的字符串格式化方式:

name = "小明"
age = 18
score = 95.567

# 基本用法
print(f"我叫{name},今年{age}岁")
# 我叫小明,今年18岁

# 表达式
print(f"明年我{age + 1}岁")           # 明年我19岁

# 格式化数字
print(f"成绩: {score:.1f}")           # 成绩: 95.6(保留1位小数)
print(f"比例: {0.12345:.2%}")         # 比例: 12.35%(百分比)
print(f"大数: {1000000:,}")           # 大数: 1,000,000(千分位)

# 对齐和填充
print(f"|{name:>10}|")               # |       小明|(右对齐)
print(f"|{name:<10}|")               # |小明       |(左对齐)
print(f"|{name:^10}|")               # |   小明    |(居中)

format() 方法

# 按位置
print("{} {} {}".format("Python", "is", "fun"))   # Python is fun
print("{1} {0} {2}".format("a", "b", "c"))        # b a c

# 按名称
print("{name} is {age} years old".format(
    name="Alice", age=25
))

# 用 format 处理模板
template = "尊敬的{name},您的订单{order_id}将于{date}送达"
print(template.format(
    name="张三",
    order_id="ORD-2026-0001",
    date="2026-05-10"
))

传统 % 格式化

C 语言风格的格式化,在老旧代码中常见:

name = "Python"
version = 3.13

print("Hello, %s!" % name)                         # Hello, Python!
print("%s version %d" % (name, version))            # Python version 3
print("PI = %.2f" % 3.14159)                        # PI = 3.14

转义字符

# 常用转义序列
print("Hello\nWorld!")      # \n 换行
print("Hello\tWorld!")      # \t 制表符
print("她说:\"你好\"")    # \" 双引号
print('It\'s fine')         # \' 单引号
print("C:\\Users\\name")   # \\ 反斜杠
print("Hello\rWorld")       # \r 回车(覆盖前面的内容)

原始字符串(Raw Strings)

原始字符串中的反斜杠不会被当作转义字符处理,在处理正则表达式和文件路径时特别有用:

# 普通字符串中,\n 会被当作换行
print("C:\new\text.txt")
# 实际输出:
# C:
# ew\text.txt(完全不是想要的)

# 原始字符串(在引号前加 r)
print(r"C:\new\text.txt")       # C:\new\text.txt
print(r"Hello\nWorld")          # Hello\nWorld(\n 不会换行)

# 正则表达式中的强大作用
import re
pattern = r"\d{3}-\d{4}-\d{4}"  # 匹配电话号码
text = "我的电话是 138-1234-5678"
match = re.search(pattern, text)
print(match.group())  # 138-1234-5678

多行字符串

# 使用三引号
long_text = """
这是一个多行字符串。
它可以跨越多行。
"""
print(long_text)

# 使用括号和普通字符串(避免缩进问题)
message = (
    "这是一个跨越多行的字符串"
    "Python 会自动拼接相邻的字符串字面量"
)
print(message)

# 使用 join 构建多行
lines = ["第一行", "第二行", "第三行"]
text = "\n".join(lines)
print(text)

字符串编码与 Unicode

编码基础

# Python 3 字符串默认使用 Unicode(UTF-8)
text = "Python编程"

# encode() - 编码为字节
utf8_bytes = text.encode("utf-8")
print(utf8_bytes)        # b'Python\xe7\xbc\x96\xe7\xa8\x8b'
print(type(utf8_bytes))  # <class 'bytes'>

gbk_bytes = text.encode("gbk")
print(gbk_bytes)         # b'Python\xb1\xe0\xb3\xcc'

# decode() - 解码为字符串
print(utf8_bytes.decode("utf-8"))  # Python编程
print(gbk_bytes.decode("gbk"))     # Python编程

# 编码错误处理
text = "中文"
try:
    text.encode("ascii")  # 中文无法用 ASCII 编码
except UnicodeEncodeError as e:
    print(f"编码错误: {e}")

Unicode 转义

# Unicode 转义
print("\u4e2d\u6587")          # 中文

# ord() - 获取字符的 Unicode 码点
print(ord("中"))               # 20013
print(ord("A"))                # 65

# chr() - 从码点获取字符
print(chr(20013))              # 中
print(chr(65))                 # A

字符串长度与字节长度

text = "Python编程"

# 字符长度(人类可读)
print(len(text))               # 8(6个英文字符 + 2个中文字符)

# 字节长度(编码后)
print(len(text.encode("utf-8")))   # 12
print(len(text.encode("gbk")))     # 10

字符串的不可变性

Python 中的字符串是不可变的,这意味着一旦创建就不能修改:

s = "Hello"
# s[0] = "h"  # TypeError! 字符串不可变

# 所有的"修改"操作实际上都是创建新字符串
s = s + ", World"  # 创建新字符串
print(s)           # Hello, World

# 验证不可变性
original = "Python"
modified = original.upper()

print(original)   # Python(原字符串不变)
print(modified)   # PYTHON(新字符串)

实践练习:文本分析器

# text_analyzer.py
print("=" * 40)
print("           文本分析器")
print("=" * 40)

text = input("请输入一段文本: ")

if not text.strip():
    print("输入为空!")
    exit()

print(f"\n--- 基本信息 ---")
print(f"字符数: {len(text)}")
print(f"单词数: {len(text.split())}")
print(f"行数: {len(text.splitlines())}")

print(f"\n--- 字符统计 ---")
print(f"大写字母: {sum(c.isupper() for c in text)}")
print(f"小写字母: {sum(c.islower() for c in text)}")
print(f"数字: {sum(c.isdigit() for c in text)}")
print(f"空格: {sum(c.isspace() for c in text)}")
print(f"其他字符: {sum(not c.isalnum() and not c.isspace() for c in text)}")

# 词频统计(简单版)
print(f"\n--- 词频统计 ---")
words = text.lower().split()
word_freq = {}
for word in words:
    word = word.strip(".,!?;:\"'()[]")
    if word:
        word_freq[word] = word_freq.get(word, 0) + 1

sorted_words = sorted(word_freq.items(), key=lambda x: x[1], reverse=True)
for word, count in sorted_words[:10]:
    print(f"  {word:12s}: {count} 次")

常见陷阱

1. 字符串拼接性能

# 在循环中拼接字符串效率低下(O(n²))
result = ""
for i in range(10000):
    result += str(i)    # 每次创建新字符串

# 使用 join(O(n))
result = "".join(str(i) for i in range(10000))

# 或者使用列表和 join
parts = []
for i in range(10000):
    parts.append(str(i))
result = "".join(parts)

2. 中文字符长度

# Python 中 len() 统计的是字符数,不是字节数
text = "你好世界"
print(len(text))  # 4

# 如果需要字节长度
print(len(text.encode("utf-8")))   # 12
print(len(text.encode("gbk")))      # 8

3. 字符串和数字拼接

# 错误
# print("结果: " + 42)   # TypeError

# 正确
print("结果: " + str(42))
print(f"结果: {42}")

小结

在这篇文章中,我们深入学习了 Python 字符串的使用:

  1. 创建字符串:单引号、双引号、三引号
  2. 索引与切片:正索引、负索引、步长切片
  3. 字符串方法:大小写转换、查找、判断、分割、替换、填充等
  4. 字符串格式化:f-string(推荐)、format()、% 格式化
  5. 转义字符与原始字符串
  6. 多行字符串的构建方法
  7. Unicode 与编码基础
  8. 字符串的不可变性

下一步

字符串是文本处理的基础。下一篇文章我们将学习列表与元组——Python 中最常用的序列类型,它们能帮我们高效地组织和处理批量数据。

实践建议:打开 Python REPL,创建一个字符串并尝试各种索引和切片操作。特别注意负索引和步长切片的行为。f-string 的各种格式化方式也值得多练练——实际工作中每天都在用。

Summary: 字符串索引切片方法格式化详解。