You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python如何解析PGN字符串:筛选以数字加点开头的棋步行存入列表

思路可行性判断

你提出的「遍历PGN拆分列表,识别以1-2位数字加英文句点开头的行作为棋步内容」的核心逻辑完全可行,这个判断规则完全贴合标准PGN格式规范:

  • 所有PGN元数据行均以方括号[开头,不会以数字加句点的格式开头
  • 用来做格式分隔的空行没有有效内容
  • 只有连续承载棋步的文本行,才会以“回合数+英文句点”的格式作为行首

但你写的示例代码存在几个需要修正的问题:

  • str.startswith()方法仅支持匹配固定字符串,无法直接实现“1位/2位数字+句点”的模糊匹配。如果硬用这个方法实现,需要把所有可能的回合数字字符串全部列举出来,维护成本极高
  • 列表追加的语法写错了:正确的追加写法是列表.append(元素),你示例里写的列表[元素]是列表索引访问的语法,运行会直接触发报错
  • 没有覆盖棋步行末尾带对局胜负标记(如1-0、0-1、1/2-1/2)的情况,直接提取的话会把多余的结果标记混入棋步内容,和你预期的输出不符
优化后的实现方案

针对上述问题,用正则表达式实现匹配逻辑会更简洁可靠,完整可运行的示例代码如下:

import re

# 示例输入的PGN拆分列表
pgn = [
    '[ECO "B08"]',
    '',
    '1.e4 d6 2.d4 Nf6 3.Nc3 g6 4.Nf3 Bg7 5.Be2 Nbd7 6.O-O O-O 7.e5 dxe5 8.dxe5 Ng4',
    '9.e6 Nde5 10.Qxd8 Rxd8 11.Nxe5 Nxe5 12.Nb5 c6 13.Nc7 Rb8 14.f4 Ng4 15.Bxg4 Bd4+',
    '16.Kh1 Bb6 17.f5 Bxc7 18.fxg6 fxg6 19.Bh6 Be5 20.Rad1 Rxd1 21.Rxd1 Bd6 22.Rf1  1-0',
    '',
    '[Event "Telechess ol1 7778"]',
]

listmove = []
# 匹配行首为1-3位数字+英文句点的棋步行
move_line_check = re.compile(r'^\d{1,3}\.')
# 匹配行末尾的对局结果标记
result_clean = re.compile(r'\s*(1-0|0-1|1/2-1/2|\*)\s*$')

for line in pgn:
    # 跳过无内容的空行
    if not line.strip():
        continue
    # 判断当前行是否为棋步内容行
    if move_line_check.match(line):
        # 清除行末尾的多余结果标记
        cleaned_content = result_clean.sub('', line).strip()
        listmove.append(cleaned_content)

# 按照预期格式拼接所有棋步行
final_moves = ','.join(listmove)
print(final_moves)

运行上述代码的输出和你给出的预期内容完全一致。
几个实现细节说明:

  • 正则匹配的范围设置为\d{1,3},覆盖了所有现实对局的回合数范围(即使是超长对局也不会超过三位数),比固定写1-2位数字的适用场景更广
  • 清洗规则只会删除行尾的对局结果标记,不会改动棋步内部的内容,保证棋步本身的完整性
  • 整个逻辑不需要依赖第三方PGN解析库,对初学者来说实现门槛很低,完全契合当前的学习需求

内容的提问来源于stack exchange,提问作者Trojan666

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.22 15:54:03