简介:《声律启蒙》上卷大字注音版是一份面向儿童国学启蒙、汉语初学者及古典文学爱好者的文档资源,通过大字与注音相结合的方式,降低古汉语对仗与声韵知识的学习门槛,帮助读者在诵读中体会平仄、押韵与对仗的规律。资源包内含1个doc文件,整体约616KB,以文档形式呈现,便于打印、批注与随身阅读。目前已有118人学习下载,适合作为家庭亲子共读或自学参考的入门材料。文档围绕上卷内容编排,涵盖对仗句式、声韵教学及标点运用等模块,读者可借此熟悉古汉语的对称美与韵律节奏,逐步掌握诗词格律的基本规律,为后续古诗文阅读与创作打下基础。无论是提升汉语听说读写能力,还是培育传统文化素养,这份注音版都能提供清晰而实用的学习路径。
1. 一份被乱码吃掉正文的《声律启蒙》注音版,到底还能怎么用
拿到「声律启蒙上卷大字注音版.doc」这个文件的人,第一反应往往是懵的:打开之后满屏都是「㈠」「㈡」「㈢」和成串的逗号、句号、分号,正文汉字几乎全丢,只剩标点和零星几个「日」「使」「奉世」「棠」「规」「táo」「rì」这样的残字。这不是文件损坏,而是典型的编码与字体映射错位——原始文档里的汉字用了某种非标准内码或嵌入字体,在转存、复制、跨平台打开的过程中被剥离,标点因为落在 ASCII 区间反而活了下来。所以这份资源真正的价值不在「直接读」,而在于它是一份结构完整的对仗骨架:上卷十五韵、每韵三则、每则两段对仗,标点位置精确保留了原文的断句节奏。对做国学类 App、儿童识字工具、古诗文语料清洗的开发者来说,它更像一份「带标点的空模板」,配合公开的《声律启蒙》通行本,可以快速重建出带注音、带平仄标注的结构化数据。适合谁:需要批量处理古籍文本的 NLP 工程师、做语文教育产品的后端、以及想拿它练手文档解析的 IT 从业者。下面从编码诊断讲到数据重建,再落到可复用的处理脚本。
2. 从乱码 doc 到结构化文本:编码诊断与清洗
2.1 先判断这份 doc 的真实格式
.doc后缀不代表它真是 OLE 复合文档。很多从网页或旧系统导出的「doc」其实是 HTML 或 RTF 改了扩展名,用file命令一测就露馅。这一步不做,后面用 python-docx 会直接抛异常。
# 查看文件真实类型,不要只看后缀 file "声律启蒙上卷大字注音版.doc" # 常见输出: # Composite Document File V2 -> 真 OLE,用 antiword 或 libreoffice # HTML document, UTF-8 -> 伪 doc,直接当 HTML 解析 # Rich Text Format -> RTF,用 striprtf逻辑说明:file读取文件头魔数,比扩展名可靠。参数上没什么可调的,重点是拿到结果后分流。如果是 OLE,优先用libreoffice --headless --convert-to txt转纯文本,比 antiword 对中文兼容更好;如果是 HTML,用 BeautifulSoup 抽文本节点即可。
2.2 用 Python 把标点骨架抽出来
乱码文档里汉字没了,但标点、括号序号、换行还在,这些恰好是切分对仗句的锚点。思路是:按「㈠㈡㈢」切则,按「,。;」切句,把每句的位置占住,等重建时按位填字。
import re def extract_skeleton(text): # 统一全角/半角标点,避免后续匹配漏掉 text = text.replace('.', '。').replace(',', ',') # 按序号切分每一则,㈠㈡㈢ 是 Unicode 带括号数字 sections = re.split(r'[㈠㈡㈢]', text) result = [] for sec in sections: if not sec.strip(): continue # 按中文标点切句,保留标点本身 clauses = re.findall(r'[^,。;]+[,。;]', sec) result.append([c.strip() for c in clauses if c.strip()]) return result with open('raw.txt', encoding='utf-8', errors='ignore') as f: skeleton = extract_skeleton(f.read()) print(len(skeleton), skeleton[0][:5])逻辑说明:re.split用序号做一级分隔,re.findall用字符类匹配「非标点+标点」的组合,这样每个对仗分句连同它的收尾标点一起被保留。errors='ignore'是关键,乱码字节直接跳过而不是报错。参数上,如果文档里序号是「(一)」而非「㈠」,把正则改成r'[((][一二三][))]'即可。
2.3 常见坑:编码探测别只信 chardet
| 现象 | 可能原因 | 处理方式 |
|---|---|---|
| 汉字全丢只剩标点 | 嵌入字体未嵌入字形 | 换原始来源,或按骨架重建 |
| 出现「?」「□」 | GBK 被当 UTF-8 读 | 用gb18030重读,它兼容 GBK/GB2312 |
| 序号变成「\u3220」 | 带括号数字被转义 | 直接按 Unicode 码点匹配 |
| 段落全挤成一行 | 原 doc 用软换行 | 按标点重新断句,不依赖\n |
提示:
gb18030是 GBK 的超集,遇到中文乱码先拿它试,比 chardet 猜编码稳得多,chardet 对短文本经常误判成 ISO-8859。
3. 按十五韵重建对仗数据:对齐通行本与注音标注
3.1 上卷十五韵的骨架映射
《声律启蒙》上卷按平水韵分十五个韵部,每韵三则,每则两段。乱码文档里的「㈠㈡㈢」正好对应每韵的三则,这个结构是重建的坐标系。先把韵部顺序固定下来,再往里填字,就不会错位。
# 上卷十五韵,顺序固定,作为重建的索引 YUUN_BU = [ "一东", "二冬", "三江", "四支", "五微", "六鱼", "七虞", "八齐", "九佳", "十灰", "十一真", "十二文", "十三元", "十四寒", "十五删" ] def build_index(skeleton): # skeleton 每项是一则,按顺序对应韵部 index = {} for i, ze in enumerate(skeleton): # 每韵三则,整除定位韵部 yun = YUUN_BU[i // 3] if i // 3 < len(YUUN_BU) else "未知" index.setdefault(yun, []).append(ze) return index逻辑说明:i // 3把连续的则映射回韵部,因为每韵恰好三则。参数上,如果文档缺失某则导致总数不是 45,需要人工核对缺口位置,不能盲目整除。这一步产出的index就是后续填字的容器。
3.2 注音数据的来源与对齐策略
大字注音版的核心是拼音。重建时拼音不能靠猜,要用公开的《声律启蒙》通行本正文做底本,再用pypinyin批量注音,最后按标点位置和骨架对齐。对齐的难点在于:通行本可能多字少字,直接按索引对会错位。
from pypinyin import pinyin, Style def annotate(line): # 逐字注音,保留声调,用于大字注音版排版 py = pinyin(line, style=Style.TONE) return list(zip(list(line), [p[0] for p in py])) # 示例:对一句通行本正文注音 print(annotate("云对雨,雪对风")) # [('云','yún'),('对','duì'),('雨','yǔ'),(',',','),...]逻辑说明:Style.TONE输出带声调符号的拼音,适合直接排版;若要数字声调(yun2)改用Style.TONE3。标点会被pinyin原样返回,所以zip后长度一致,不会错位。参数上,多音字是最大变量,pypinyin默认按词频选音,古籍场景建议加载自定义词典load_phrases_dict修正「斜」「衰」这类古音。
3.3 用 difflib 做骨架与正文的模糊对齐
当通行本和骨架句数不一致时,硬对齐会崩。用difflib.SequenceMatcher按标点序列做模糊匹配,找出插入/缺失位置,比逐句比对鲁棒。
import difflib def align(skeleton_clauses, text_clauses): sm = difflib.SequenceMatcher(None, skeleton_clauses, text_clauses) pairs = [] for tag, i1, i2, j1, j2 in sm.get_opcodes(): if tag == 'equal': pairs.extend(zip(range(i1, i2), range(j1, j2))) # 'insert'/'delete' 记录缺口,人工复核 return pairs逻辑说明:get_opcodes返回 equal/replace/insert/delete 四类操作,equal 段直接建立索引映射,其余段落标记为待人工核对。参数上,SequenceMatcher的autojunk对短序列建议设 False,避免它把高频标点当噪声过滤掉。
4. 批量处理与导出:脚本化生成可检索的注音文本
4.1 批量注音并导出 Markdown 表格
单篇处理完,真正要交付的是可检索、可导入数据库的结构。把每则对仗导出成「韵部 / 上句 / 下句 / 拼音」四列的 Markdown 或 CSV,方便后续做全文检索或喂给前端。
import csv def export_csv(index, out_path): with open(out_path, 'w', newline='', encoding='utf-8-sig') as f: w = csv.writer(f) w.writerow(['韵部', '则', '上句', '下句', '上句拼音', '下句拼音']) for yun, zes in index.items(): for n, ze in enumerate(zes, 1): # 假设每则已切成上下两段 up, down = ze[0], ze[1] if len(ze) > 1 else '' w.writerow([yun, n, up, down, ' '.join(p[0] for p in pinyin(up, style=Style.TONE)), ' '.join(p[0] for p in pinyin(down, style=Style.TONE))])逻辑说明:utf-8-sig带 BOM,Excel 直接双击不乱码,这是给非技术同事交付时的实用细节。参数上,如果只要纯文本给程序读,去掉-sig用utf-8。pinyin返回嵌套列表,p[0]取拼音串。
4.2 用 jieba 做韵脚检索
重建完数据,检索需求就来了:查某个韵脚出现过哪些对仗。中文分词后按韵母归并,能快速建倒排索引。
import jieba from pypinyin import lazy_pinyin, Style def rhyme_index(lines): idx = {} for line in lines: # 取每句末字的韵母,作为韵脚 last = line.strip(',。;')[-1] yunmu = lazy_pinyin(last, style=Style.FINALS)[0] idx.setdefault(yunmu, []).append(line) return idx逻辑说明:Style.FINALS只取韵母,忽略声母,正好对应传统押韵的判定。参数上,lazy_pinyin比pinyin快,适合大批量;末字取[-1]前要先剥标点,否则韵脚会变成「,」。
| 导出格式 | 适用场景 | 关键参数 |
|---|---|---|
| CSV (utf-8-sig) | Excel 校对、非技术交付 | 带 BOM 防乱码 |
| JSON | 前端渲染、API 返回 | ensure_ascii=False |
| SQLite | 本地全文检索 | FTS5 建虚拟表 |
| Markdown | 静态站点、文档 | 表格对齐即可 |
注意:批量注音前先对正文做繁简统一,
opencc转一遍,否则同一字繁简两套拼音会污染韵脚索引。
5. 进阶:把注音数据接进全文检索与前端渲染
数据重建完,最后一公里是让它能被搜、能被看。SQLite 的 FTS5 扩展是本地全文检索最省事的方案,建一张虚拟表,把上句、下句、拼音都塞进去,中文用unicode61分词器配合预分词即可。
-- 建 FTS5 虚拟表,content 指向真实表 CREATE VIRTUAL TABLE shenglyu_fts USING fts5( yun, up, down, up_py, down_py, tokenize = 'unicode61' ); -- 查询含「风」的对仗,拼音列也能命中 SELECT yun, up, down FROM shenglyu_fts WHERE shenglyu_fts MATCH '风' LIMIT 10;逻辑说明:unicode61对中文按字切分,够用;若要按词,需在入库前用 jieba 把文本切成空格分隔再存。MATCH支持列限定,如up_py:feng可只搜上句拼音。参数上,数据量大时加content=''建外部内容表,省空间。
前端渲染大字注音,常见做法是用 ruby 标签,把拼音放在汉字上方,字号用text-emphasis或绝对定位控制。一个最小可用的结构是每个字包一层<ruby>,拼音进<rt>,CSS 里把rt字号设成主字的 0.5 倍、颜色调淡,就得到接近纸质注音版的观感。如果要做成可点击查韵脚,给每个末字绑事件,查上面那张 FTS 表返回同韵对仗即可。这套流程跑通后,一份乱码 doc 就变成了可检索、可注音、可前端渲染的国学语料,比直接读原文的用途大得多。
本文还有配套的精品资源,点击获取