大家好,我是 SiKi老师。对白表里的台词可能包含逗号、双引号,甚至换行。如果工具用split(',')拆一条 CSV 文本,台词中的逗号会不会也被拆走?本文用自拟的两列对白数据检查这个问题,不读取真实游戏资源,也没有使用第三方剧情素材。
本地实测环境是 Windows、Python 3.12.14。所有输入均为内存字符串,CSV 解析使用 Python 标准库;没有验证 Unity、Godot 的导入流程、编码识别或实际游戏显示。本文关注“字段边界怎样读对”,不重复讨论完整的表头和业务内容校验。
一 先复现台词被拆成两段
最小示例中,说话者是guide,台词是Go, now。CSV 用双引号包住包含逗号的字段:
raw='speaker,line\nguide,"Go, now"\n'print(raw.splitlines()[1].split(','))本地输出为:
['guide', '"Go', ' now"']原本两列被拆成了三段,外层引号还留在结果里。split只是按给定字符串分隔,不会解释 CSV 中引号保护字段的规则。把多出来的片段再用逗号拼回去也不是通用修复办法,因为一行可能含有多个带引号的字段,不能靠“剩下的都当台词”解决所有输入。
如果数据协议明确不允许台词含逗号,应当把违反协议的数据报告出来;如果协议允许,就需要按约定的 CSV 格式解析。不要为了让错误的拆分代码通过,悄悄删除作者台词里的标点。
二 用CSV解析器识别字段边界
对同一份输入使用标准库:
importcsvimportio raw='speaker,line\nguide,"Go, now"\n'rows=list(csv.reader(io.StringIO(raw,newline='')))print(rows[0])print(rows[1])输出是:
['speaker', 'line'] ['guide', 'Go, now']默认格式使用逗号分隔、双引号作为引用字符,台词里的逗号被保留为字段内容。解析后的结果仍是字符串列表,reader不会自动判断角色是否存在、台词是否为空,或表格是否含有全部必需字段。
这里用StringIO保持示例独立。实际读取文本文件时,Python 官方文档建议以newline=''打开 CSV 文件,避免换行处理干扰包含换行的引用字段;文件编码仍需按输入协议指定。本文没有实际读取未知编码文件,不能据此承诺任何 CSV 都能直接导入。
三 台词换行时一条记录可能跨多行
再把台词改成两行:
raw='speaker,line\nguide,"first\nsecond"\n'reader=csv.reader(io.StringIO(raw,newline=''))rows=list(reader)print(rows[1])print(len(raw.splitlines()),len(rows),reader.line_num)本地结果为:
['guide', 'first\nsecond'] 3 2 3源文本有三行,解析后只有两条记录,其中一条是表头。reader.line_num记录读过的源文本行数,不能直接当作解析记录数,也不能把两条记录都算成两句游戏台词。
如果先splitlines()再逐行独立解析,这句跨行台词的完整引用字段就会被切断。对这类输入应把完整文本流交给同一个解析器;日志里也要区分源文本行号、数据记录序号和游戏对白 ID,避免让协作者按错误的行号定位内容。
四 双引号与分隔符要遵循同一协议
台词本身带双引号时,本例按默认格式将其写成两个连续双引号:
raw='guide,"Say ""yes"""\n'print(next(csv.reader(io.StringIO(raw,newline=''))))结果是['guide', 'Say "yes"']。这些引号的含义来自 CSV 格式规则,不能先把所有引号全局删掉,否则台词内容会被改写。
有些工具约定用分号分隔。独立实测中,guide;"Go, now"配合delimiter=';'才得到两列;把分号数据当成默认逗号格式读取,不能得到预期的字段边界。我会优先读取双方明确约定的格式,不凭文件扩展名猜分隔符,也不把自动探测说成一定正确。
五 解析成功后还要做内容验收
本地另测了guide,:解析后第二个字段是空字符串,它不会自动变成缺失键或None。另外,输入guide,"unfinished且未闭合引用时,使用csv.reader(..., strict=True)遍历会抛出csv.Error;默认的strict为假,本文没有把默认解析器说成一定拒绝所有坏格式。
严格模式也不是完整对白校验器。语法可解析之后,仍需按项目规则检查列数、表头、对白 ID、必填内容、允许的长度与版本对应关系,再决定是否生成资源文件。不要在解析失败后拿上一次的结果冒充本次成功,也不要把空台词自动替换为随意生成的句子。
排查时可以先复制一条脱敏且保留原始引号的记录,在临时字符串上复现,记录分隔符、引用规则、源行数和解析结果。本文全部测试都没有写入游戏工程;看到正确的两列输出,只说明这组示例的字段边界被读对,不代表引擎内呈现或音频匹配已验收。
依据:Python 3.12 官方 csv 文档,包括格式参数、换行要求、strict与line_num的含义。