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知、蚩、诗、日、资、雌、思等字拼作zhichishirizicisi。
韵母ㄦ写成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(晕);ü上两点省略。
ü行的韵跟声母jqx拼的时候写成ju(居)qu(区)xu(虚)ü上两点也省略但是跟声母nl拼的时候仍然写成nü(女)lü(吕)。
iouueiuen前面加声母的时候写成iuuiun。例如niu(牛)gui(归)lun(论)。
在给汉字注音的时候为了使拼式简短ng可以省作ŋ。
"""
import re
from typing import Text
# u -> ü
UV_MAP = {
'u': 'ü',
'ū': 'ǖ',
'ú': 'ǘ',
'ǔ': 'ǚ',
'ù': 'ǜ',
}
U_TONES = set(UV_MAP.keys())
# ü行的韵跟声母jqx拼的时候写成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',
'': 'ioū',
'': 'ioú',
'': 'ioǔ',
'': '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',
'': 'ueī',
'': 'ueí',
'': 'ueǐ',
'': '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:
"""ü 转换,还原原始的韵母
ü行的韵跟声母jqx拼的时候写成ju(居)qu(区)xu(虚),ü上两点也省略;
但是跟声母nl拼的时候仍然写成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 转换,还原原始的韵母
iouueiuen前面加声母的时候写成iuuiun。
例如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 转换,还原原始的韵母
iouueiuen前面加声母的时候写成iuuiun。
例如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 转换,还原原始的韵母
iouueiuen前面加声母的时候写成iuuiun。
例如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)
# ü行的韵跟声母jqx拼的时候
pinyin = convert_uv(pinyin)
# iouueiuen前面加声母的时候
pinyin = convert_iou(pinyin)
pinyin = convert_uei(pinyin)
pinyin = convert_uen(pinyin)
return pinyin