
本文介绍如何使用 Python 精准解析结构化文本文件(如以 | 分隔的成绩单),从中可靠提取成绩与学分等关键数值,避免误匹配(如课程名中的数字),并生成可用于 GPA 计算的标准数据结构。
本文介绍如何使用 python 精准解析结构化文本文件(如以 `|` 分隔的成绩单),从中可靠提取成绩与学分等关键数值,避免误匹配(如课程名中的数字),并生成可用于 gpa 计算的标准数据结构。
在实际数据处理中,我们常需从非标准格式的 .txt 文件中提取结构化信息——例如本例中以竖线 | 分隔的课程记录:
Government | 97.0% | 3.0 Credits | History | 87.0% | 3.0 Credits | ...
目标是将每行转化为形如 (97.0, 3.0) 的元组,并最终构成列表 [(97.0, 3.0), (87.0, 3.0), ...],为后续 GPA 计算提供干净输入。
直接遍历字符(如原代码中用 i.isdecimal())极易出错:它会捕获课程名中的数字(如 "English 1" 中的 1),且无法区分语义位置,导致 76.04.0 这类粘连错误。正确思路是分层抽象:先按行切分 → 再按 | 拆解字段 → 最后在指定字段内精准提取数值。
以下是推荐的稳健实现:
立即学习“Python免费学习笔记(深入)”;
# 定义关键常量,提升可维护性
DECIMAL_CHARS = set('0123456789.') # 允许的数值字符集
GRADE_FIELD_INDEX = 1 # 成绩所在字段索引(0-based)
CREDIT_FIELD_INDEX = 2 # 学分所在字段索引
def extract_decimal(s: str) -> str:
"""从字符串中过滤出所有数字和小数点,忽略其他字符(如 %、空格、单位)"""
return ''.join(c for c in s if c in DECIMAL_CHARS)
def parse_grade_line(line: str) -> tuple[float, float]:
"""解析单行文本,返回 (成绩, 学分) 元组"""
# 按 '|' 分割并去除首尾空格
fields = [field.strip() for field in line.split('|')]
# 确保字段数量足够(防御性编程)
if len(fields) < 3:
raise ValueError(f"行格式异常,字段不足3个: {line.strip()}")
grade_str = extract_decimal(fields[GRADE_FIELD_INDEX])
credit_str = extract_decimal(fields[CREDIT_FIELD_INDEX])
# 转换为浮点数(自动处理 '97.0' → 97.0)
return float(grade_str), float(credit_str)
# 主流程:读取文件并批量解析
try:
with open("Grades.txt", "r", encoding="utf-8") as f:
# 过滤空行和纯空白行
lines = [line.strip() for line in f if line.strip()]
records = [parse_grade_line(line) for line in lines]
print("解析结果(成绩, 学分):")
print(records)
# 示例输出: [(97.0, 3.0), (87.0, 3.0), (76.0, 4.0), ...]
except FileNotFoundError:
print("错误:未找到 Grades.txt 文件,请检查路径。")
except ValueError as e:
print(f"解析错误:{e}")✅ 关键优势说明:
- 语义定位:通过 fields[1] 和 fields[2] 明确限定提取范围,彻底规避课程名中数字的干扰;
- 鲁棒过滤:extract_decimal() 仅保留数字与小数点,自动剥离 %、Credits、空格等噪声;
- 错误防护:检查字段数量、捕获常见异常(文件不存在、格式异常),便于调试;
- 可扩展性强:若后续需提取课程名,只需添加 fields[0];若分隔符变更,仅需修改 split('|')。
⚠️ 注意事项:
- 若文本含中文或特殊编码,请务必指定 encoding="utf-8"(Windows 默认 ANSI 可能报错);
- 对于更复杂格式(如嵌套分隔符、缺失字段、多行记录),建议升级至 csv 模块(配合 delimiter='|')或正则表达式(re.findall(r'(\d+\.\d+)%.*?(\d+\.\d+)\s+Credits', line));
- 生产环境建议增加日志记录与数据验证(如成绩是否在 0–100 区间)。
掌握这种「分层解析 + 字段定位 + 精准过滤」的思维模式,你将能从容应对各类现实文本数据源——无论它是成绩单、日志文件还是 API 响应片段。










