必须用程序自动拆字+对齐生成,因手动易错位漏音、无法处理多音字和混排;正则全局替换会误标地名/多音字,且不识别语境;可靠路径是先用正则分块再逐块处理,汉字块调lazy_pinyin()转拼音并校验长度,非汉字块原样保留,严格按ruby模板拼接并配必要CSS。

不能靠手写,必须用程序自动拆字+对齐生成;手动写多字 ruby 结构极易错位、漏音、破坏语义,且无法应对多音字和混排文本。
为什么不能直接用正则全局替换
常见错误是写 text.replace(/([\u4e00-\u9fff])/g, '<ruby>$1<rt>$1-pinyin</rt></ruby>')——这会把所有汉字无差别套拼音,但「重庆」会被标成 chōng qìng(错音),「长」在「长度」里该读 cháng,在「生长」里该读 zhǎng,程序根本不知道上下文。
- 正则无法识别词性、地名、人名或语境,只能机械匹配字符
- 遇到 emoji、全角标点、组合字符(如「ā」)时,
lazy_pinyin()可能返回空或异常长度,导致rb和rt数量不等 - 非汉字块(如「Python 3.12」)若被误处理,会产出空
rt或崩溃
用 pypinyin + 正则分块才是可靠路径
核心逻辑是:先切块 → 再逐块判断 → 汉字块调 lazy_pinyin() → 非汉字块原样保留。这样既保语义,又防错位。
- 用
re.findall(r'[\u4e00-\u9fff]+|[^\u4e00-\u9fff]+', text)把文本切成「纯汉字段」和「非汉字段」 - 对每个汉字段,用
pypinyin.lazy_pinyin(segment, errors='ignore')逐字转拼音(errors='ignore'防止非汉字字符报错) - 确保拼音列表长度 == 汉字数量,否则跳过该段(说明有不可转字符,不强标)
- 拼接时严格按
<ruby><rb>{char}</rb><rt>{pinyin}</rt><rp>(</rp><rp>)</rp></ruby>模板,rp必须成对且只含括号
生成的 HTML 必须带基础 CSS 才能正常显示
光有结构不够,Chrome/Firefox/Safari 对 rt 的默认渲染差异极大:Safari 缩放更狠,Firefox 不缩放,Chrome 可能裁顶。不加样式 = 大概率错位或看不见。
立即学习“前端免费学习笔记(深入)”;
- 必须设
ruby { display: ruby; },强制浏览器启用 ruby 排版引擎(尤其 Safari) -
rt要显式设font-size: 0.7em; line-height: 1; ruby-position: over;,禁用vertical-align - 父容器加
white-space: nowrap;,防止换行撕裂字-音对应关系 - 避免给
ruby设display: inline-block或float,会切断基字定位
最易被忽略的是 rp 的成对性和内容限制:它不是装饰,是降级关键。漏掉一个 <rp>)</rp>,旧版 Safari 或 Outlook 就会显示「汉(hàn」这种半截括号,可读性归零。别省,也别往里塞空格或文字。



















