You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
PaddleSpeech/third_party/python-pinyin/pypinyin/standard.py

155 lines
5.4 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

"""
处理汉语拼音方案中的一些特殊情况
汉语拼音方案:
* https://zh.wiktionary.org/wiki/%E9%99%84%E5%BD%95:%E6%B1%89%E8%AF%AD%E6%8B%BC%E9%9F%B3%E6%96%B9%E6%A1%88
* http://www.moe.edu.cn/s78/A19/yxs_left/moe_810/s230/195802/t19580201_186000.html
“知、蚩、诗、日、资、雌、思”等七个音节的韵母用i,即:知、蚩、诗、日、资、雌、思等字拼作zhi,chi,shi,ri,zi,ci,si。
韵母ㄦ写成er,用作韵尾的时候写成r。例如:“儿童”拼作ertong,“花儿”拼作huar。
i行的韵母,前面没有声母的时候,写成yi(衣),ya(呀),ye(耶),yao(腰),you(忧),yan(烟),yin(因),yang(央),ying(英),yong(雍)。
u行的韵母,前面没有声母的时候,写成wu(乌),wa(蛙),wo(窝),wai(歪),wei(威),wan(弯),wen(温),wang(汪),weng(翁)。
ü行的韵母,前面没有声母的时候,写成yu(迂),yue(约),yuan(冤),yun(晕);ü上两点省略。
ü行的韵跟声母j,q,x拼的时候,写成ju(居),qu(区),xu(虚),ü上两点也省略;但是跟声母n,l拼的时候,仍然写成nü(女),lü(吕)。
iou,uei,uen前面加声母的时候,写成iu,ui,un。例如niu(牛),gui(归),lun(论)。
在给汉字注音的时候,为了使拼式简短,ng可以省作ŋ。
"""
import re
from typing import Text
# u -> ü
UV_MAP = {
'u': 'ü',
'ū': 'ǖ',
'ú': 'ǘ',
'ǔ': 'ǚ',
'ù': 'ǜ',
}
U_TONES = set(UV_MAP.keys())
# ü行的韵跟声母j,q,x拼的时候,写成ju(居),qu(区),xu(虚)
UV_RE = re.compile(
r'^(j|q|x)({tones})(.*)$'.format(tones='|'.join(UV_MAP.keys())))
I_TONES = set(['i', 'ī', 'í', 'ǐ', 'ì'])
# iu -> iou
IU_MAP = {
'iu': 'iou',
'iū': 'ioū',
'iú': 'ioú',
'iǔ': 'ioǔ',
'iù': 'ioù',
}
IU_TONES = set(IU_MAP.keys())
IU_RE = re.compile(r'^([a-z]+)({tones})$'.format(tones='|'.join(IU_TONES)))
# ui -> uei
UI_MAP = {
'ui': 'uei',
'uī': 'ueī',
'uí': 'ueí',
'uǐ': 'ueǐ',
'uì': 'ueì',
}
UI_TONES = set(UI_MAP.keys())
UI_RE = re.compile(r'([a-z]+)({tones})$'.format(tones='|'.join(UI_TONES)))
# un -> uen
UN_MAP = {
'un': 'uen',
'ūn': 'ūen',
'ún': 'úen',
'ǔn': 'ǔen',
'ùn': 'ùen',
}
UN_TONES = set(UN_MAP.keys())
UN_RE = re.compile(r'([a-z]+)({tones})$'.format(tones='|'.join(UN_TONES)))
def convert_zero_consonant(pinyin: Text) -> Text:
"""零声母转换,还原原始的韵母
i行的韵母,前面没有声母的时候,写成yi(衣),ya(呀),ye(耶),yao(腰),
you(忧),yan(烟),yin(因),yang(央),ying(英),yong(雍)。
u行的韵母,前面没有声母的时候,写成wu(乌),wa(蛙),wo(窝),wai(歪),
wei(威),wan(弯),wen(温),wang(汪),weng(翁)。
ü行的韵母,前面没有声母的时候,写成yu(迂),yue(约),yuan(冤),
yun(晕);ü上两点省略。
"""
# y: yu -> v, yi -> i, y -> i
if pinyin.startswith('y'):
# 去除 y 后的拼音
no_y_py = pinyin[1:]
first_char = no_y_py[0] if len(no_y_py) > 0 else None
# yu -> ü: yue -> üe
if first_char in U_TONES:
pinyin = UV_MAP[first_char] + pinyin[2:]
# yi -> i: yi -> i
elif first_char in I_TONES:
pinyin = no_y_py
# y -> i: ya -> ia
else:
pinyin = 'i' + no_y_py
return pinyin
# w: wu -> u, w -> u
if pinyin.startswith('w'):
# 去除 w 后的拼音
no_w_py = pinyin[1:]
first_char = no_w_py[0] if len(no_w_py) > 0 else None
# wu -> u: wu -> u
if first_char in U_TONES:
pinyin = pinyin[1:]
# w -> u: wa -> ua
else:
pinyin = 'u' + pinyin[1:]
return pinyin
return pinyin
def convert_uv(pinyin: Text) -> Text:
"""ü 转换,还原原始的韵母
ü行的韵跟声母j,q,x拼的时候,写成ju(居),qu(区),xu(虚),ü上两点也省略;
但是跟声母n,l拼的时候,仍然写成nü(女),lü(吕)。
"""
return UV_RE.sub(
lambda m: ''.join((m.group(1), UV_MAP[m.group(2)], m.group(3))), pinyin)
def convert_iou(pinyin: Text) -> Text:
"""iou 转换,还原原始的韵母
iou,uei,uen前面加声母的时候,写成iu,ui,un。
例如niu(牛),gui(归),lun(论)。
"""
return IU_RE.sub(lambda m: m.group(1) + IU_MAP[m.group(2)], pinyin)
def convert_uei(pinyin: Text) -> Text:
"""uei 转换,还原原始的韵母
iou,uei,uen前面加声母的时候,写成iu,ui,un。
例如niu(牛),gui(归),lun(论)。
"""
return UI_RE.sub(lambda m: m.group(1) + UI_MAP[m.group(2)], pinyin)
def convert_uen(pinyin: Text) -> Text:
"""uen 转换,还原原始的韵母
iou,uei,uen前面加声母的时候,写成iu,ui,un。
例如niu(牛),gui(归),lun(论)。
"""
return UN_RE.sub(lambda m: m.group(1) + UN_MAP[m.group(2)], pinyin)
def convert_finals(pinyin: Text) -> Text:
"""还原原始的韵母"""
# i,u,ü 行的韵母,前面没有声母的时候
pinyin = convert_zero_consonant(pinyin)
# ü行的韵跟声母j,q,x拼的时候
pinyin = convert_uv(pinyin)
# iou,uei,uen前面加声母的时候
pinyin = convert_iou(pinyin)
pinyin = convert_uei(pinyin)
pinyin = convert_uen(pinyin)
return pinyin