Python实现粤语拼音标注(Jyutping):从词库到API服务

0 阅读2分钟

背景

在香港工作的内地工程师,都会遇到一个具体的问题:

掘金.png

同事发来一段粤语文字,看不懂,也不知道怎么学。

市面上的粤语学习工具,要么是给游客用的日常会话,要么是学术性质的拼音系统,没有一个从「内地工程师学粤语」视角设计的工具。

于是我自己做了一套。


核心问题

粤语拼音(Jyutping)标注的核心挑战有两个:

  1. 语料库:需要一个覆盖常用字的粤拼对照表
  2. 算法:如何快速对任意粤语文字进行标注

技术方案

1. 粤拼词库构建

核心数据来源:公开的粤拼词典 + 自己补充的语料

python

复制

2. 常见错误与处理

坑一:未收录字符

粤拼词库无法覆盖所有汉字,需要降级处理:

python

复制

def safe_jyutping(text: str, fallback: str = "?") -> str:
    """安全标注,未知字符返回?"""
    annotated = jyutping_annotate(text)
    return "".join(
        p["jyutping"] if p["known"] else fallback
        for p in annotated
    )

坑二:多音字

粤语多音字处理是最麻烦的地方:

python

复制

# 常见多音字处理
AMBIGUOUS_CHARS = {
    "着": {"zyu3": "穿", "zoek3": "去", "zo6": "结果"},
    "分": {"fan1": "分开的分", "fan6": "分给的分"},
}

def disambiguate(char: str, context: str) -> str:
    """基于上下文消歧(简化版)"""
    if char not in AMBIGUOUS_CHARS:
        return jyutping_lookup(char)
    # 实际项目需要NLP模型辅助,这里用规则简化
    return list(AMBIGUOUS_CHARS[char].values())[0]

3. FastAPI服务封装

python

复制

运行效果:

POST /annotate
{
  "text": "我唔知你想哋",
  "include_tone": true
}

Response:
{
  "data": [
    {"char": "我", "jyutping": "ngo5", "known": true},
    {"char": " ", "jyutping": null, "known": false},
    {"char": "唔", "jyutping": "m4", "known": true},
    {"char": "知", "jyutping": "zi1", "known": true},
    ...
  ]
}

项目结构

cantonese-tool/
├── app/
│   ├── __init__.py
│   ├── main.py          # FastAPI入口
│   ├── router.py        # API路由
│   └── models.py        # 数据模型
├── data/
│   ├── jyutping_dict.json   # 粤拼词库
│   └── ambiguous_chars.json  # 多音字表
├── tests/
│   └── test_annotate.py
├── requirements.txt
└── README.md

数据结果

  • 词库规模:常用字覆盖率约 80% (3000+汉字)
  • API响应时间:< 50ms(本地部署)
  • 月访问量(工具网站):5000+ (主要来自内地学粤语用户)

下一步扩展

  1. 接入NLP模型处理多音字消歧
  2. 开放API接口供其他开发者调用
  3. 支持批量文件处理

踩坑总结

描述解决方法
词库覆盖不足日常用字超出3000常用字范围持续补充 + 未知字符fallback
多音字消歧同一字符不同读音规则+模型双重判断
性能优化全量加载词库内存占用高按需加载 + LRU缓存

讨论

你在香港工作有遇到过理解粤语的困难吗?是怎么解决的?