一、Python 字符串基础
在 Python 3 中,字符串是由 Unicode 码点组成的不可变序列。这是理解所有字符处理的基础。
1. 字符串的创建
使用单引号 '...'、双引号 "..."、三引号 '''...''' 或 """..."""。
s1 = 'Hello'
s2 = "World"
s3 = '''这是一个
多行字符串'''2. 字符串的不可变性
字符串一旦创建,其内容就不能改变。任何“修改”操作都会生成一个新的字符串对象。
s = "apple"
# s[0] = 'b' # 这会报错:TypeError
# 正确的方式是创建一个新字符串
new_s = 'b' + s[1:] # new_s 为 "bpple"3. 原始字符串 (Raw Strings)
在字符串前加 r 或 R,反斜杠 \ 不会被当作转义字符。这在处理正则表达式和文件路径时非常有用。
path = r'C:\Users\Name\Documents' # 不会被解析为转义序列
regex_pattern = r'\d+' # 匹配数字的正则表达式4. 格式化字符串 (f-Strings) - Python 3.6+
一种非常高效和易读的字符串格式化方法。
name = "Alice"
age = 30
greeting = f"Hello, {name}. You are {age} years old."
# 输出:Hello, Alice. You are 30 years old.
# 可以在表达式内进行计算
message = f"In 5 years, you will be {age + 5}."二、核心字符串操作与方法
字符串支持所有通用的序列操作(索引、切片、in, len(), min(), max()),同时还拥有大量内置方法。
1. 查找与替换
str.find(sub),str.index(sub):查找子串,返回首次出现的索引。find找不到返回 -1,index找不到会抛出ValueError。str.rfind(sub),str.rindex(sub):从右边开始查找。str.replace(old, new[, count]):替换字符串,count指定替换次数。
s = "hello world"
print(s.find('o')) # 4
print(s.rfind('o')) # 7
print(s.replace('l', 'L', 2)) # heLLo world2. 分割与连接
str.split(sep=None, maxsplit=-1):根据分隔符sep分割字符串,返回列表。str.rsplit(...):从右边开始分割。str.partition(sep):将字符串分成三部分(sep之前的部分, sep, sep之后的部分)。str.join(iterable):用字符串将可迭代对象中的元素连接起来。
data = "apple,banana,cherry"
fruits = data.split(',') # ['apple', 'banana', 'cherry']
new_data = '-'.join(fruits) # 'apple-banana-cherry'
# partition 常用于解析字符串
url = "https://www.example.com"
protocol, separator, domain = url.partition('://')3. 大小写转换
str.lower():转为小写。str.upper():转为大写。str.title():每个单词首字母大写。str.capitalize():整个字符串首字母大写。str.swapcase():大小写互换。
4. 判断类方法 (返回布尔值)
str.startswith(prefix),str.endswith(suffix):检查开头/结尾。str.isalpha():是否全是字母。str.isdigit():是否全是数字。str.isalnum():是否全是字母或数字。str.isspace():是否全是空白字符。str.islower(),str.isupper():检查大小写格式。
"abc123".isalnum() # True
" ".isspace() # True
"file.txt".endswith('.txt') # True5. 去除空白与填充
str.strip([chars]):去除两端的指定字符(默认为空白符)。str.lstrip([chars]),str.rstrip([chars]):去除左/右端的指定字符。str.center(width[, fillchar]):居中填充。str.ljust(width[, fillchar]),str.rjust(width[, fillchar]):左/右对齐填充。str.zfill(width):用0在左边填充。
s = " hello "
s.strip() # 'hello'
"42".zfill(5) # '00042'
"hi".center(10, '*') # '****hi****'三、高级字符处理
1. 正则表达式 (re 模块)
对于复杂的模式匹配、查找和替换,正则表达式是终极武器。
常见场景:
- 验证:邮箱、电话号码、密码强度。
- 提取:从日志文件或HTML中提取特定信息。
- 分割:使用复杂的分隔符(如多个空格、标点符号)。
- 替换:进行复杂的文本重写。
import re
text = "My phone numbers are 123-456-7890 and (555) 123-4567."
# 查找所有电话号码
# 模式解释:\d 匹配数字,{3} 匹配3次,[...] 匹配括号或空格等
pattern = r'\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}'
phones = re.findall(pattern, text)
print(phones) # ['123-456-7890', '(555) 123-4567']
# 替换,将所有数字替换为 ‘X’
anonymized = re.sub(r'\d', 'X', text)
print(anonymized) # ‘My phone numbers are XXX-XXX-XXXX and (XXX) XXX-XXXX.’2. 字符串模板 (string.Template)
一种更简单、更安全的字符串替换方式,尤其适合处理用户提供的模板(避免了 % 或 format 可能带来的安全问题)。
from string import Template
t = Template('Hello, $name! Today is $day.')
result = t.substitute(name='Bob', day='Monday')
print(result) # Hello, Bob! Today is Monday.四、编码与解码 (Bytes & Unicode)
这是处理文件、网络通信和不同数据源时的关键。
- Unicode:字符串在内存中的表示形式,是一个抽象的字符集。
- 编码 (Encode):将
str(Unicode) 转换为bytes(用于存储或传输)。 - 解码 (Decode):将
bytes转换回str(Unicode)。
常见编码: utf-8, ascii, gbk, latin-1
# 编码:字符串 -> 字节串
s = "你好,世界"
b = s.encode('utf-8') # b'\xe4\xbd\xa0\xe5\xa5\xbd\xef\xbc\x8c\xe4\xb8\x96\xe7\x95\x8c'
# 解码:字节串 -> 字符串
original_s = b.decode('utf-8') # '你好,世界'
# 处理文件时指定编码
with open('file.txt', 'r', encoding='utf-8') as f:
content = f.read()
with open('file.txt', 'w', encoding='gbk') as f:
f.write(content)处理乱码: 大部分文本处理问题(如乱码)都源于编码和解码时使用的字符集不一致。
五、经典使用场景
数据清洗与预处理
# 清洗用户输入
user_input = " UsER@Example.COM \n"
cleaned_input = user_input.strip().lower() # ‘user@example.com‘
# 从CSV行解析数据
csv_line = ‘data1, data2, "data3, with comma", data4‘
# 简单 split(’,’) 会出错,需要使用 csv 模块
import csv
from io import StringIO
reader = csv.reader(StringIO(csv_line))
row = next(reader) # 正确解析出 [’data1‘, ’ data2‘, ’data3, with comma‘, ’ data4‘]日志分析
log_line = ‘2023-10-27 14:35:21 [ERROR] User login failed for ID: alice‘
# 提取错误级别和时间
parts = log_line.split(’ ‘, 3) # 分割3次
timestamp = parts[0] + ’ ’ + parts[1]
log_level = parts[2].strip(’[]‘)
message = parts[3]生成动态SQL或HTML
# 使用 f-string 动态生成SQL查询(注意:真实项目应使用参数化查询防止注入!)
table_name = ‘users‘
user_id = 123
query = f“SELECT * FROM {table_name} WHERE id = {user_id}”URL 解析与构建
# 使用 urllib.parse
from urllib.parse import urlparse, urljoin, urlencode
url = ‘https://www.example.com/path/page?query=python#fragment‘
parsed = urlparse(url)
print(parsed.netloc) # ’www.example.com‘
print(parsed.query) # ’query=python‘
# 构建查询参数
params = {’q‘: ’python tutorial‘, ’page‘: 2}
query_string = urlencode(params) # ’q=python+tutorial&page=2‘模板渲染(简易版)
# 一个非常简单的模板引擎
template = “”“
Dear $customer,
Your order #$order_id is now $status.
“””
data = {’customer‘: ’Alice‘, ’order_id‘: ’12345‘, ’status‘: ’shipped‘}
for key, value in data.items():
template = template.replace(f’${key}‘, str(value))
print(template)总结与最佳实践
- 选择正确的工具:
- 简单查找/替换:用字符串方法 (
find,replace)。 - 复杂模式:用正则表达式 (
re模块)。 - 固定位置/格式:用切片和
split。
- 牢记不可变性:大量字符串拼接操作(如在循环中使用
+或+=)性能极差。应使用.join()方法。
# 错误 (低效)
result = ""
for s in large_list_of_strings:
result += s
# 正确 (高效)
result = "".join(large_list_of_strings)- 处理编码问题:遵循 “尽早解码,晚点编码” 的原则。在程序内部始终使用
str(Unicode) 类型,只在输入/输出时进行编解码,并明确指定编码格式。 - 注意安全性:当字符串内容来自用户输入时,要警惕。不要直接用字符串拼接来生成命令、查询或HTML,应使用参数化查询或专业的模板引擎。
















