2Python Cookbook(第3版)

字符串与文本

文本处理

正则表达式字符串格式化Unicode处理文本解析

🎯 AI 时代的学习建议:不要只读理论。理解这一章的设计动机(为什么需要这个概念?)和边界条件(什么情况下会失效?)。当 AI 生成的代码涉及这些概念时,你能判断它是否用对了场景。AI 能帮你总结内容,但无法替代你亲手阅读、思考、建立直觉的过程。

第2章:字符串与文本

一、导读

1.1 本章学习目标

第2章讲解 Python 字符串和文本处理的技巧:正则表达式、字符串格式化、Unicode 处理。

本章核心学习目标:

  • 掌握正则表达式:re 模块的核心用法
  • 理解字符串格式化:f-string、format、%
  • 掌握 Unicode 处理:编码、解码、规范化

1.2 为什么本章如此重要

文本处理是编程中最常见的任务。Python 提供了强大的字符串处理能力,掌握这些技巧能大幅提高开发效率。

1.3 核心问题引导

正则表达式的贪婪匹配和非贪婪匹配有什么区别?

f-string 比 format 有什么优势?

Unicode 规范化为什么重要?


二、核心概念详解

2.1 正则表达式

python
import re

# 基本匹配
text = "Contact: alice@example.com or bob@test.org"
emails = re.findall(r'[\w.]+@[\w.]+', text)
print(emails)  # ['alice@example.com', 'bob@test.org']

# 分组
date_pattern = r'(\d{4})-(\d{2})-(\d{2})'
match = re.search(date_pattern, "Date: 2024-03-15")
if match:
    year, month, day = match.groups()
    print(f"Year: {year}, Month: {month}")

# 命名分组
pattern = r'(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})'
match = re.search(pattern, "2024-03-15")
print(match.group('year'))  # 2024

# 替换
text = "Hello World"
result = re.sub(r'(\w+)\s+(\w+)', r'\2 \1', text)
print(result)  # World Hello

# 预编译正则
email_re = re.compile(r'[\w.+-]+@[\w-]+\.[\w.]+')
matches = email_re.findall("test@example.com, admin@site.org")

2.2 字符串格式化

python
name = "Alice"
age = 30
score = 95.678

# f-string (Python 3.6+)
print(f"Name: {name}, Age: {age}")
print(f"Score: {score:.2f}")  # 95.68
print(f"{'center':*^20}")     # *******center********

# format
print("Name: {}, Age: {}".format(name, age))
print("Score: {:.2f}".format(score))

# % 格式化 (旧式)
print("Name: %s, Age: %d" % (name, age))

# 数字格式化
print(f"{1234567:,}")        # 1,234,567
print(f"{0.25:.1%}")         # 25.0%
print(f"{42:08b}")           # 00101010

2.3 Unicode 处理

python
# 编码和解码
text = "Hello 世界"
encoded = text.encode('utf-8')
print(encoded)  # b'Hello \xe4\xb8\x96\xe7\x95\x8c'
decoded = encoded.decode('utf-8')
print(decoded)  # Hello 世界

# Unicode 规范化
import unicodedata
s1 = 'café'         # 组合字符
s2 = 'cafe\u0301'   # 基础字符 + 组合重音
print(s1 == s2)     # False

# NFC 规范化
nfc = unicodedata.normalize('NFC', s2)
print(s1 == nfc)    # True

# 去除重音符号
def remove_accents(text):
    nfkd = unicodedata.normalize('NFKD', text)
    return ''.join(c for c in nfkd if not unicodedata.combining(c))

print(remove_accents('café'))  # cafe

三、实战案例

3.1 案例一:HTML 标签提取

python
import re

def extract_links(html):
    """从 HTML 中提取所有链接"""
    pattern = r'<a\s+[^>]*href=["\']([^"\']+)["\'][^>]*>(.*?)</a>'
    links = re.findall(pattern, html, re.IGNORECASE | re.DOTALL)
    return [(url, text.strip()) for url, text in links]

html = '''
<a href="https://example.com">Example</a>
<a class="link" href="/about">About Us</a>
'''
print(extract_links(html))
# [('https://example.com', 'Example'), ('/about', 'About Us')]

四、本章小结

正则表达式是文本处理的利器

f-string 是最简洁的格式化方式

Unicode 规范化确保文本比较的正确性


五、思考与练习

re.DOTALL 和 re.MULTILINE 有什么区别?

如何处理包含 BOM 的 UTF-8 文件?


2/12字符串与
0%