1. 文本处理的基础概念与核心价值
文本处理是计算机科学中最基础却又最常被忽视的技能之一。简单来说,它指的是对字符串数据进行各种操作和转换的技术集合。从日常工作中的Excel数据处理,到程序开发中的日志分析,再到大数据领域的信息提取,文本处理无处不在。
我见过太多技术团队因为缺乏系统的文本处理能力而陷入困境——某个产品团队曾花费两周时间手动整理用户反馈,而实际上一个简单的Python脚本就能在几分钟内完成同样的工作;另一个数据分析团队因为不会处理CSV文件中的特殊字符,导致整个月的报表数据出现偏差。
文本处理的核心价值在于:
- 自动化替代人工:将重复性的文本操作转化为可重复执行的代码
- 提高数据质量:通过规范化处理消除不一致性和错误
- 信息提取:从非结构化文本中提取有价值的结构化数据
- 数据转换:在不同格式和系统间进行数据迁移和交换
2. 文本处理的四大基础操作
2.1 字符串查找与匹配
字符串查找是文本处理中最基础的操作。在实际项目中,我经常看到开发者过度依赖简单的"包含"检查,而忽略了更精确的匹配方式。以下是几种实用的查找技术:
python复制# 基础查找
text = "订单号:ORD-2023-00123"
if "ORD" in text: # 简单但不够精确
print("找到订单")
# 更精确的查找方式
import re
pattern = r"ORD-\d{4}-\d{5}" # 使用正则表达式精确匹配订单格式
if re.search(pattern, text):
print("找到格式正确的订单")
提示:在关键业务场景中,永远不要依赖简单的字符串包含检查,应该使用正则表达式或特定格式验证。
2.2 字符串分割与切片
文本分割是将字符串拆分为更有用部分的关键技术。最常见的分割场景包括CSV数据处理、日志分析和URL解析等。
python复制# 基础分割
log_entry = "2023-08-15 14:30:22 [ERROR] 用户登录失败"
parts = log_entry.split() # 默认按空格分割
print(parts) # ['2023-08-15', '14:30:22', '[ERROR]', '用户登录失败']
# 高级分割 - 处理CSV中的复杂情况
csv_line = '"张三,工程师",30,"北京,朝阳区"'
import csv
reader = csv.reader([csv_line])
for row in reader:
print(row) # 正确处理了包含逗号的值
我在处理一个电商项目时发现,简单的split()在处理产品名称中的特殊字符时会导致数据错乱。后来改用csv模块才解决了这个问题。
2.3 字符串替换与清洗
数据清洗是文本处理中最耗时的环节之一。以下是几种常见的清洗场景和解决方案:
python复制# 基础替换
text = "价格:$1,000.00"
clean_text = text.replace("$", "").replace(",", "")
print(clean_text) # "价格:1000.00"
# 使用正则表达式的高级替换
import re
text = "联系电话:123-456-7890"
clean_phone = re.sub(r"\D", "", text) # 移除非数字字符
print(clean_phone) # "1234567890"
# 处理全角/半角字符统一化
text = "Hello World" # 全角字符
normalized = text.translate(str.maketrans(' HelloWorld', ' HelloWorld'))
print(normalized) # "Hello World"
注意:在替换操作中,务必考虑字符编码问题。我曾遇到一个项目因为UTF-8和GBK编码混用导致替换失败的情况。
2.4 字符串格式化与拼接
现代Python提供了多种字符串格式化方式,每种都有其适用场景:
python复制# 传统%格式化
msg = "欢迎%s,您是第%d位访客" % ("张三", 1000)
# str.format()方法
msg = "欢迎{name},您是第{count}位访客".format(name="张三", count=1000)
# f-string (Python 3.6+)
name = "张三"
count = 1000
msg = f"欢迎{name},您是第{count}位访客"
# 性能关键场景下的字符串拼接
parts = ["欢迎", name, ",您是第", str(count), "位访客"]
msg = "".join(parts) # 比+操作符更高效
在性能敏感的应用中(如处理百万级日志条目),字符串拼接方式的选择会显著影响性能。我曾经通过将+操作符改为join()方式,使一个日志处理脚本的运行时间从45秒降到了8秒。
3. 正则表达式:文本处理的瑞士军刀
3.1 正则表达式基础语法精要
正则表达式是文本处理中最强大的工具之一,但也是学习曲线最陡峭的部分。以下是必须掌握的核心语法:
python复制import re
# 基础匹配
pattern = r"\d+" # 匹配一个或多个数字
text = "订单号12345"
match = re.search(pattern, text)
if match:
print(match.group()) # "12345"
# 常用元字符
# . 任意字符(除换行)
# ^ 字符串开始
# $ 字符串结束
# * 0次或多次
# + 1次或多次
# ? 0次或1次
# {n} 恰好n次
# {n,} 至少n次
# {n,m} n到m次
# [] 字符集合
# | 或
# () 分组
# 实用示例:提取邮箱
text = "联系我们:support@example.com, sales@example.org"
emails = re.findall(r"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b", text)
print(emails) # ['support@example.com', 'sales@example.org']
3.2 正则表达式高级技巧
掌握基础语法后,这些高级技巧可以解决更复杂的问题:
python复制# 非贪婪匹配
html = "<div>内容1</div><div>内容2</div>"
# 贪婪匹配会匹配到最后一个</div>
greedy = re.search(r"<div>(.*)</div>", html).group(1)
print(greedy) # "内容1</div><div>内容2"
# 非贪婪匹配
non_greedy = re.search(r"<div>(.*?)</div>", html).group(1)
print(non_greedy) # "内容1"
# 前后查找
text = "产品价格:¥100.00"
price = re.search(r"(?<=¥)\d+\.\d+", text).group()
print(price) # "100.00"
# 命名分组
text = "2023-08-15"
match = re.search(r"(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})", text)
print(match.groupdict()) # {'year': '2023', 'month': '08', 'day': '15'}
提示:复杂的正则表达式应该始终添加注释,可以使用re.VERBOSE标志:
python复制pattern = re.compile(r""" \b # 单词边界 [A-Z0-9._%+-]+ # 用户名 @ # @符号 [A-Z0-9.-]+ # 域名 \. # 点 [A-Z]{2,} # 顶级域名 \b # 单词边界 """, re.VERBOSE | re.IGNORECASE)
3.3 正则表达式性能优化
不当使用正则表达式可能导致严重的性能问题。以下是我总结的优化经验:
-
预编译正则表达式:对于重复使用的模式,先编译再使用
python复制# 不好的做法 for text in texts: re.search(r"\d+", text) # 好的做法 pattern = re.compile(r"\d+") for text in texts: pattern.search(text) -
避免回溯灾难:当正则表达式包含嵌套量词时可能导致性能急剧下降
python复制# 危险的正则 - 可能导致回溯灾难 re.search(r"(a+)+$", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaa!") # 更安全的写法 re.search(r"a+$", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaa!") -
使用原子分组:防止不必要的回溯
python复制# 普通分组 re.search(r"(ab|a)c", "a" * 100 + "c") # 慢 # 原子分组(?>...) re.search(r"(?>ab|a)c", "a" * 100 + "c") # 快 -
合理使用锚点:帮助引擎快速定位
python复制# 没有锚点 - 需要搜索整个字符串 re.search(r"\d{4}-\d{2}-\d{2}", text) # 有锚点 - 可以更快定位 re.search(r"^\d{4}-\d{2}-\d{2}$", text) # 如果日期是整行内容
4. 实际项目中的文本处理案例
4.1 日志文件分析实战
日志分析是文本处理最常见的应用场景之一。以下是一个完整的日志分析流程:
python复制import re
from collections import defaultdict
def analyze_logs(log_file):
error_pattern = re.compile(r"\[(ERROR|WARN)\] (.+)")
ip_pattern = re.compile(r"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}")
user_agent_pattern = re.compile(r'"(.+?)"$')
error_counts = defaultdict(int)
ip_counts = defaultdict(int)
user_agents = set()
with open(log_file, 'r', encoding='utf-8', errors='ignore') as f:
for line in f:
# 提取错误级别和消息
error_match = error_pattern.search(line)
if error_match:
level, message = error_match.groups()
error_counts[level] += 1
# 特殊错误处理
if "Timeout" in message:
error_counts["Timeout"] += 1
# 提取IP地址
ip_match = ip_pattern.search(line)
if ip_match:
ip = ip_match.group()
ip_counts[ip] += 1
# 提取User-Agent
ua_match = user_agent_pattern.search(line)
if ua_match:
user_agents.add(ua_match.group(1))
return {
"error_counts": dict(error_counts),
"top_ips": sorted(ip_counts.items(), key=lambda x: x[1], reverse=True)[:10],
"unique_user_agents": len(user_agents)
}
# 使用示例
results = analyze_logs("app.log")
print(f"错误统计: {results['error_counts']}")
print(f"访问最多的IP: {results['top_ips']}")
print(f"唯一User-Agent数量: {results['unique_user_agents']}")
注意:处理日志文件时总会遇到编码问题。使用errors='ignore'参数可以跳过无法解码的字符,但更好的做法是确定日志的实际编码(通常是UTF-8或本地编码如GBK)。
4.2 数据清洗与规范化
数据清洗是数据科学项目中最耗时的环节。以下是一个完整的数据清洗函数:
python复制import re
import unicodedata
def clean_text(text):
"""全面文本清洗函数"""
if not isinstance(text, str):
text = str(text)
# 1. 标准化Unicode字符
text = unicodedata.normalize('NFKC', text)
# 2. 移除不可见字符
text = re.sub(r'[\u200b-\u200f\u202a-\u202e]', '', text)
# 3. 替换各种空白字符为单个空格
text = re.sub(r'\s+', ' ', text).strip()
# 4. 处理特殊引号
text = re.sub(r'[`´‘’"“”]', "'", text)
# 5. 处理连字符
text = re.sub(r'[-﹣-‐⁃−—]', '-', text)
# 6. 移除控制字符
text = re.sub(r'[\x00-\x1f\x7f-\x9f]', '', text)
# 7. 处理全角字符
text = text.translate(str.maketrans(
'!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~',
'!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'
))
return text
def clean_csv_file(input_file, output_file):
"""清洗整个CSV文件"""
import csv
with open(input_file, 'r', encoding='utf-8', newline='') as fin, \
open(output_file, 'w', encoding='utf-8', newline='') as fout:
reader = csv.DictReader(fin)
writer = csv.DictWriter(fout, fieldnames=reader.fieldnames)
writer.writeheader()
for row in reader:
cleaned_row = {k: clean_text(v) if v else v for k, v in row.items()}
writer.writerow(cleaned_row)
# 使用示例
clean_csv_file("dirty_data.csv", "clean_data.csv")
这个清洗函数处理了我在实际项目中遇到的大多数数据质量问题,包括:
- 混合编码问题
- 不可见字符
- 不一致的标点符号
- 全角/半角字符混用
- 特殊空白字符
4.3 模板系统实现
文本模板是许多应用的核心功能。以下是比str.format()更强大的模板引擎实现:
python复制import re
from datetime import datetime
class TemplateEngine:
def __init__(self, template):
self.template = template
self.functions = {
'upper': str.upper,
'lower': str.lower,
'capitalize': str.capitalize,
'date': lambda fmt: datetime.now().strftime(fmt)
}
def render(self, context):
def replacer(match):
expr = match.group(1).strip()
# 处理函数调用
if '|' in expr:
var_name, *funcs = map(str.strip, expr.split('|'))
value = context.get(var_name, '')
for func in funcs:
if func in self.functions:
if '(' in func: # 带参数的函数
func_name, args = re.match(r'(\w+)\((.*)\)', func).groups()
value = self.functions[func_name](args)
else: # 无参数函数
value = self.functions[func](value)
return str(value)
# 简单变量替换
return str(context.get(expr, ''))
# 支持{{变量}}和{% if 条件%}...{% endif %}语法
template = re.sub(r'{%\s*if\s+(.+?)\s*%}(.*?){%\s*endif\s*%}',
lambda m: m.group(2) if bool(context.get(m.group(1), False)) else '',
self.template, flags=re.DOTALL)
return re.sub(r'{{\s*(.+?)\s*}}', replacer, template)
# 使用示例
template = """
欢迎{{ name | upper }}!
{% if is_vip %}
尊贵的VIP会员,您有{{ points }}积分可用。
{% endif %}
今天是{{ 'date' | date('%Y年%m月%d日') }}。
"""
engine = TemplateEngine(template)
context = {
'name': '张三',
'is_vip': True,
'points': 1000
}
print(engine.render(context))
这个模板引擎支持:
- 变量替换
- 过滤器函数
- 条件语句
- 自定义函数
我在一个邮件通知系统中使用类似的实现,支持了20多种不同的邮件模板,比使用Jinja2等大型模板引擎更轻量且性能更好。
5. 性能优化与大型文本处理
5.1 内存高效处理大文件
处理GB级别的文本文件时,内存使用成为关键考量。以下是几种处理大文件的技巧:
python复制# 1. 逐行处理 - 最基本的方式
with open('large_file.txt', 'r', encoding='utf-8') as f:
for line in f:
process(line) # 一次只处理一行
# 2. 使用生成器处理
def read_in_chunks(file_path, chunk_size=1024*1024): # 1MB chunks
with open(file_path, 'r', encoding='utf-8') as f:
while True:
chunk = f.read(chunk_size)
if not chunk:
break
yield chunk
for chunk in read_in_chunks('huge_file.txt'):
process_chunk(chunk)
# 3. 使用内存映射文件
import mmap
with open('large_file.txt', 'r+b') as f:
with mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ) as mm:
# 可以像操作字符串一样操作mm,但实际只在访问时加载到内存
if mm.find(b'important data') != -1:
print("找到关键数据")
5.2 多进程文本处理
对于CPU密集型的文本处理任务,可以使用多进程加速:
python复制from multiprocessing import Pool
import re
def process_line(line):
# 模拟耗时的文本处理
return re.sub(r'\d+', lambda m: str(int(m.group())*2), line)
def parallel_text_processing(input_file, output_file, workers=4):
with open(input_file, 'r', encoding='utf-8') as fin, \
open(output_file, 'w', encoding='utf-8') as fout:
with Pool(workers) as pool:
results = pool.imap(process_line, fin, chunksize=1000)
for processed_line in results:
fout.write(processed_line)
# 使用示例
parallel_text_processing('input.txt', 'output.txt', workers=8)
提示:多进程处理文本时,需要注意:
- 每个工作进程应该有足够的任务量以抵消进程创建开销
- IO操作仍然是瓶颈,考虑将读写与处理分离
- 在Linux上使用fork()可能比Windows上的spawn更高效
5.3 使用专业文本处理工具
对于超大规模文本处理,专业工具可能更合适:
-
AWK - 流式文本处理利器
bash复制# 统计日志中每个IP的出现次数 awk '{print $1}' access.log | sort | uniq -c | sort -nr -
sed - 流式文本编辑器
bash复制# 替换文件中的所有旧域名为新域名 sed -i 's/old-domain.com/new-domain.com/g' file.txt -
ripgrep (rg) - 比grep更快的搜索工具
bash复制# 递归搜索目录中包含"error"的Python文件 rg -t py "error" -
jq - JSON处理神器
bash复制# 从JSON日志中提取特定字段 cat log.json | jq '.timestamp, .message'
在实际项目中,我经常组合使用这些工具。例如,先用ripgrep快速定位相关日志条目,再用jq提取和转换特定字段,最后用Python进行更复杂的分析。
6. 文本处理的最佳实践与陷阱
6.1 编码问题:永恒的挑战
文本处理中最常见的问题就是字符编码。以下是我总结的编码处理原则:
-
尽早规范化编码:在数据输入的第一时间转换为统一的内部编码(推荐UTF-8)
python复制def read_text(file_path): encodings = ['utf-8', 'gbk', 'latin-1'] # 按可能性排序 for enc in encodings: try: with open(file_path, 'r', encoding=enc) as f: return f.read() except UnicodeDecodeError: continue raise ValueError(f"无法解码文件: {file_path}") -
处理编码声明:有些文件包含BOM(Byte Order Mark)或编码声明
python复制import codecs def remove_bom(text): if text.startswith(codecs.BOM_UTF8.decode('utf-8')): return text[len(codecs.BOM_UTF8.decode('utf-8')):] return text -
安全输出:输出文本时明确指定编码
python复制with open('output.txt', 'w', encoding='utf-8', errors='replace') as f: f.write(processed_text)
6.2 性能陷阱与优化
文本处理中常见的性能陷阱:
-
字符串拼接:在循环中使用+操作符拼接字符串
python复制# 不好 - 每次+都创建新字符串 result = "" for part in parts: result += part # 好 - join()一次性分配内存 result = "".join(parts) -
过度使用正则表达式:简单字符串操作有时更快
python复制# 不好 - 过度使用正则 cleaned = re.sub(r"\s+", " ", text) # 更好 - 简单字符串操作 cleaned = " ".join(text.split()) -
不必要的编译:重复编译相同的正则表达式
python复制# 不好 - 每次循环都编译 for text in texts: re.search(r"\d+", text) # 好 - 预编译正则 pattern = re.compile(r"\d+") for text in texts: pattern.search(text)
6.3 可维护性建议
-
注释复杂的正则表达式:使用re.VERBOSE模式
python复制phone_re = re.compile(r""" \b # 单词边界 (\d{3,4}) # 区号 [- ]? # 可选分隔符 (\d{7,8}) # 电话号码 \b # 单词边界 """, re.VERBOSE) -
创建文本处理工具函数库:将常用操作封装成函数
python复制# text_utils.py def extract_emails(text): """从文本中提取所有邮箱地址""" pattern = r"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b" return re.findall(pattern, text, re.IGNORECASE) def clean_whitespace(text): """规范化空白字符""" return " ".join(text.split()) -
编写单元测试:确保文本处理函数的正确性
python复制import unittest class TestTextUtils(unittest.TestCase): def test_extract_emails(self): text = "联系我:user@example.com 或 support@test.org" result = extract_emails(text) self.assertEqual(result, ["user@example.com", "support@test.org"]) def test_clean_whitespace(self): text = "太多 空格\t和\n换行" self.assertEqual(clean_whitespace(text), "太多 空格 和 换行")
7. 现代Python中的文本处理新特性
7.1 f-string的进阶用法
Python 3.6引入的f-string彻底改变了字符串格式化方式。以下是一些高级用法:
python复制# 1. 表达式求值
width = 10
precision = 4
value = 12.34567
print(f"result: {value:{width}.{precision}}") # 'result: 12.35'
# 2. 多行f-string
name = "Alice"
age = 30
message = (
f"Name: {name}\n"
f"Age: {age}\n"
f"Next year: {age + 1}"
)
print(message)
# 3. 调试打印
x = 42
print(f"{x=}") # 'x=42'
# 4. 格式化日期
from datetime import datetime
now = datetime.now()
print(f"{now:%Y-%m-%d %H:%M:%S}") # '2023-08-15 14:30:22'
7.2 类型注解与文本处理
Python的类型注解可以显著提高文本处理代码的可维护性:
python复制from typing import List, Dict, Pattern, Union
import re
def process_text(
text: str,
patterns: Dict[str, Union[str, Pattern]],
replacements: Dict[str, str]
) -> str:
"""
根据模式字典替换文本
:param text: 要处理的文本
:param patterns: 模式字典,键是模式名,值可以是字符串或编译后的正则表达式
:param replacements: 替换字典,键是模式名,值是对应的替换字符串
:return: 处理后的文本
"""
result = text
for name, pattern in patterns.items():
if name in replacements:
if isinstance(pattern, str):
result = result.replace(pattern, replacements[name])
else:
result = pattern.sub(replacements[name], result)
return result
# 使用示例
patterns = {
"email": re.compile(r"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b"),
"phone": r"\d{3}-\d{4}-\d{4}"
}
replacements = {
"email": "[EMAIL]",
"phone": "[PHONE]"
}
text = "联系我:user@example.com 或 123-4567-8910"
clean_text = process_text(text, patterns, replacements)
print(clean_text) # "联系我:[EMAIL] 或 [PHONE]"
7.3 结构化模式匹配(Python 3.10+)
Python 3.10引入的模式匹配语法非常适合复杂的文本解析:
python复制def parse_log_entry(entry: str) -> dict:
"""解析日志条目"""
match entry.split(maxsplit=3):
case [date, time, "INFO", message]:
return {"level": "INFO", "date": date, "time": time, "message": message}
case [date, time, "ERROR", message]:
return {"level": "ERROR", "date": date, "time": time, "message": message}
case [date, time, level, message]:
return {"level": level, "date": date, "time": time, "message": message}
case _:
return {"level": "UNKNOWN", "message": entry}
# 使用示例
log1 = "2023-08-15 14:30:22 INFO 用户登录成功"
log2 = "2023-08-15 14:31:45 ERROR 数据库连接失败"
print(parse_log_entry(log1))
print(parse_log_entry(log2))
8. 文本处理在不同领域的应用实例
8.1 自然语言处理(NLP)预处理
NLP项目中的文本预处理通常包括以下步骤:
python复制import re
import unicodedata
from nltk.tokenize import word_tokenize
from nltk.corpus import stopwords
import nltk
nltk.download('punkt')
nltk.download('stopwords')
def preprocess_text(text, lang='english'):
"""NLP文本预处理流水线"""
# 1. 标准化Unicode
text = unicodedata.normalize('NFKC', text)
# 2. 转换为小写
text = text.lower()
# 3. 移除特殊字符和数字
text = re.sub(r'[^a-zA-Z\s]', '', text)
# 4. 分词
tokens = word_tokenize(text, language=lang)
# 5. 移除停用词
stop_words = set(stopwords.words(lang))
tokens = [word for word in tokens if word not in stop_words]
# 6. 移除短词
tokens = [word for word in tokens if len(word) > 2]
return tokens
# 使用示例
text = "Natural Language Processing (NLP) is a subfield of AI. It's awesome!"
tokens = preprocess_text(text)
print(tokens) # ['natural', 'language', 'processing', 'subfield', 'awesome']
8.2 数据提取与转换
从非结构化文本中提取结构化数据:
python复制import re
from datetime import datetime
def extract_invoice_data(text):
"""从发票文本中提取结构化数据"""
# 提取发票号
invoice_no = re.search(r"发票号[::]\s*(\w+)", text)
invoice_no = invoice_no.group(1) if invoice_no else None
# 提取日期
date_match = re.search(r"日期[::]\s*(\d{4})[年/-](\d{1,2})[月/-](\d{1,2})日?", text)
if date_match:
date = f"{date_match.group(1)}-{date_match.group(2).zfill(2)}-{date_match.group(3).zfill(2)}"
else:
date = None
# 提取金额
amount = re.search(r"金额[::]\s*[\¥¥$]?\s*([\d,]+\.\d{2})", text)
amount = float(amount.group(1).replace(',', '')) if amount else None
# 提取项目
items = []
for match in re.finditer(r"(\d+)\.\s*(.+?)\s*(\d+)\s*[\¥¥$]?\s*([\d,]+\.\d{2})", text):
items.append({
"item_no": int(match.group(1)),
"description": match.group(2),
"quantity": int(match.group(3)),
"unit_price": float(match.group(4).replace(',', ''))
})
return {
"invoice_no": invoice_no,
"date": date,
"total_amount": amount,
"items": items
}
# 使用示例
invoice_text = """
发票号:INV-2023-001
日期:2023年8月15日
1. 笔记本电脑 2 ¥8,999.00
2. 无线鼠标 5 ¥199.00
3. 键盘保护膜 3 ¥59.00
金额:¥9,354.00
"""
data = extract_invoice_data(invoice_text)
print(data)
8.3 代码生成与模板渲染
使用文本处理技术生成代码:
python复制def generate_model_code(class_name, fields):
"""根据字段定义生成Python模型类代码"""
field_defs = []
init_params = []
init_assignments = []
for field in fields:
field_name = field['name']
field_type = field.get('type', 'str')
default = field.get('default', None)
# 字段定义
if default is not None:
field_def = f" {field_name}: {field_type} = {default!r}"
else:
field_def = f" {field_name}: {field_type}"
field_defs.append(field_def)
# __init__参数
if default is not None:
init_params.append(f"{field_name}: {field_type} = {default!r}")
else:
init_params.append(f"{field_name}: {field_type}")
# __init__赋值
init_assignments.append(f" self.{field_name} = {field_name}")
# 组合代码模板
code = f"""class {class_name}:
\"\"\"{class_name}模型类\"\"\"
"""
code += "\n".join(field_defs) + "\n\n"
code += f" def __init__(self, {', '.join(init_params)}):\n"
code += "\n".join(init_assignments) + "\n"
return code
# 使用示例
fields = [
{"name": "id", "type": "int"},
{"name": "username", "type": "str"},
{"name": "email", "type": "str"},
{"name": "is_active", "type": "bool", "default": True}
]
print(generate_model_code("User", fields))
这个代码生成器可以输出如下Python类:
python复制class User:
"""User模型类"""
id: int
username: str
email: str
is_active: bool = True
def __init__(self, id: int, username: str, email: str, is_active: bool = True):
self.id = id
self.username = username
self.email = email
self.is_active = is_active
9. 文本处理工具链推荐
9.1 Python标准库中的文本处理模块
Python标准库提供了丰富的文本处理工具:
-
string - 字符串操作基础
python复制import string # 字符串常量 print(string.digits) # '0123456789' print(string.punctuation) # !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~ # 模板字符串 t = string.Template("$name owes $amount") print(t.substitute(name="Alice", amount="100")) # "Alice owes 100" -
re - 正则表达式
python复制import re # 前面已经详细介绍 -
difflib - 差异比较
python复制from difflib import ndiff text1 = "Hello World" text2 = "Hello Python" for diff in ndiff(text1.splitlines(), text2.splitlines()): print(diff) -
textwrap - 文本包装
python复制import textwrap text = "这是一段很长的文本,需要自动换行以适应特定宽度。" print(textwrap.fill(text, width=10)) -
csv - CSV文件处理
python复制import csv # 前面已经介绍
9.2 第三方文本处理库
- regex - 更强大的正则表达式
python复制import regex # pip install regex # 支持更复杂的正则特性 text = "Some words: café, naïve, über" matches =
