Restore 0.1.5 version from stash
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""汉字拼音转换工具."""
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from pypinyin.compat import PY2
|
||||
from pypinyin.constants import ( # noqa
|
||||
Style,
|
||||
STYLE_NORMAL, NORMAL,
|
||||
STYLE_TONE, TONE,
|
||||
STYLE_TONE2, TONE2,
|
||||
STYLE_TONE3, TONE3,
|
||||
STYLE_INITIALS, INITIALS,
|
||||
STYLE_FIRST_LETTER, FIRST_LETTER,
|
||||
STYLE_FINALS, FINALS,
|
||||
STYLE_FINALS_TONE, FINALS_TONE,
|
||||
STYLE_FINALS_TONE2, FINALS_TONE2,
|
||||
STYLE_FINALS_TONE3, FINALS_TONE3,
|
||||
STYLE_BOPOMOFO, BOPOMOFO,
|
||||
STYLE_BOPOMOFO_FIRST, BOPOMOFO_FIRST,
|
||||
STYLE_CYRILLIC, CYRILLIC,
|
||||
STYLE_CYRILLIC_FIRST, CYRILLIC_FIRST
|
||||
)
|
||||
from pypinyin.core import ( # noqa
|
||||
pinyin, lazy_pinyin, slug, load_single_dict, load_phrases_dict
|
||||
)
|
||||
|
||||
__title__ = 'pypinyin'
|
||||
__version__ = '0.55.0'
|
||||
__author__ = 'mozillazg, 闲耘'
|
||||
__license__ = 'MIT'
|
||||
__copyright__ = 'Copyright (c) 2016 mozillazg, 闲耘'
|
||||
__all__ = [
|
||||
'pinyin', 'lazy_pinyin', 'slug',
|
||||
'load_single_dict', 'load_phrases_dict',
|
||||
'Style',
|
||||
'STYLE_NORMAL', 'NORMAL',
|
||||
'STYLE_TONE', 'TONE',
|
||||
'STYLE_TONE2', 'TONE2',
|
||||
'STYLE_TONE3', 'TONE3',
|
||||
'STYLE_INITIALS', 'INITIALS',
|
||||
'STYLE_FINALS', 'FINALS',
|
||||
'STYLE_FINALS_TONE', 'FINALS_TONE',
|
||||
'STYLE_FINALS_TONE2', 'FINALS_TONE2',
|
||||
'STYLE_FINALS_TONE3', 'FINALS_TONE3',
|
||||
'STYLE_FIRST_LETTER', 'FIRST_LETTER',
|
||||
'STYLE_BOPOMOFO', 'BOPOMOFO',
|
||||
'STYLE_BOPOMOFO_FIRST', 'BOPOMOFO_FIRST',
|
||||
'STYLE_CYRILLIC', 'CYRILLIC',
|
||||
'STYLE_CYRILLIC_FIRST', 'CYRILLIC_FIRST'
|
||||
]
|
||||
if PY2:
|
||||
# fix "TypeError: Item in ``from list'' not a string" on Python 2
|
||||
__all__ = [x.encode('utf-8') for x in __all__]
|
||||
@@ -0,0 +1,50 @@
|
||||
from typing import Any
|
||||
|
||||
from . import compat
|
||||
from . import constants
|
||||
from . import core
|
||||
|
||||
__title__ = ... # type: Any
|
||||
__version__ = ... # type: Any
|
||||
__author__ = ... # type: Any
|
||||
__license__ = ... # type: Any
|
||||
__copyright__ = ... # type: Any
|
||||
__all__ = ... # type: Any
|
||||
|
||||
PY2 = compat.PY2
|
||||
|
||||
Style = constants.Style
|
||||
STYLE_NORMAL = constants.STYLE_NORMAL
|
||||
NORMAL = constants.NORMAL
|
||||
STYLE_TONE = constants.STYLE_TONE
|
||||
TONE = constants.TONE
|
||||
STYLE_TONE2 = constants.STYLE_TONE2
|
||||
TONE2 = constants.TONE2
|
||||
STYLE_TONE3 = constants.STYLE_TONE3
|
||||
TONE3 = constants.TONE3
|
||||
STYLE_INITIALS = constants.STYLE_INITIALS
|
||||
INITIALS = constants.INITIALS
|
||||
STYLE_FIRST_LETTER = constants.STYLE_FIRST_LETTER
|
||||
FIRST_LETTER = constants.FIRST_LETTER
|
||||
STYLE_FINALS = constants.STYLE_FINALS
|
||||
FINALS = constants.FINALS
|
||||
STYLE_FINALS_TONE = constants.STYLE_FINALS_TONE
|
||||
FINALS_TONE = constants.FINALS_TONE
|
||||
STYLE_FINALS_TONE2 = constants.STYLE_FINALS_TONE2
|
||||
FINALS_TONE2 = constants.FINALS_TONE2
|
||||
STYLE_FINALS_TONE3 = constants.STYLE_FINALS_TONE3
|
||||
FINALS_TONE3 = constants.FINALS_TONE3
|
||||
STYLE_BOPOMOFO = constants.STYLE_BOPOMOFO
|
||||
BOPOMOFO = constants.BOPOMOFO
|
||||
STYLE_BOPOMOFO_FIRST = constants.STYLE_BOPOMOFO_FIRST
|
||||
BOPOMOFO_FIRST = constants.BOPOMOFO_FIRST
|
||||
STYLE_CYRILLIC = constants.STYLE_CYRILLIC
|
||||
CYRILLIC = constants.CYRILLIC
|
||||
STYLE_CYRILLIC_FIRST = constants.STYLE_CYRILLIC_FIRST
|
||||
CYRILLIC_FIRST = constants.CYRILLIC_FIRST
|
||||
|
||||
pinyin = core.pinyin
|
||||
lazy_pinyin = core.lazy_pinyin
|
||||
slug = core.slug
|
||||
load_single_dict = core.load_single_dict
|
||||
load_phrases_dict = core.load_phrases_dict
|
||||
@@ -0,0 +1,6 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
from pypinyin.runner import main
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -0,0 +1,7 @@
|
||||
# reference: https://github.com/pyinstaller/hooksample/blob/master/src/pyi_hooksample/__pyinstaller/__init__.py # noqa
|
||||
|
||||
import os
|
||||
|
||||
|
||||
def get_hook_dirs():
|
||||
return [os.path.dirname(__file__)]
|
||||
@@ -0,0 +1,4 @@
|
||||
from typing import Text, List
|
||||
|
||||
|
||||
def get_hook_dirs() -> List[Text]: ...
|
||||
@@ -0,0 +1,6 @@
|
||||
# reference: https://github.com/pyinstaller/hooksample/blob/master/src/pyi_hooksample/__pyinstaller/hook-pyi_hooksample.py # noqa
|
||||
|
||||
from PyInstaller.utils.hooks import collect_data_files # type: ignore
|
||||
|
||||
datas = collect_data_files(
|
||||
'pypinyin', excludes=['__pyinstaller'])
|
||||
@@ -0,0 +1,30 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import sys
|
||||
|
||||
SUPPORT_UCS4 = len('\U00020000') == 1
|
||||
|
||||
PY2 = sys.version_info < (3, 0)
|
||||
|
||||
subversion = getattr(sys, 'subversion', [''])
|
||||
# 这些 Python 实现虽然是 Python 2 但字符串的行为跟 Python 3 是一样的
|
||||
if subversion[0] in (
|
||||
'IronPython',
|
||||
):
|
||||
PY2 = False # pragma: no cover
|
||||
|
||||
if not PY2:
|
||||
text_type = str
|
||||
bytes_type = bytes
|
||||
else:
|
||||
text_type = unicode # noqa
|
||||
bytes_type = str
|
||||
|
||||
try:
|
||||
callable_check = callable # noqa
|
||||
except NameError:
|
||||
def callable_check(obj):
|
||||
return hasattr(obj, '__call__')
|
||||
@@ -0,0 +1,14 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from typing import Any, List, Text, ByteString
|
||||
|
||||
SUPPORT_UCS4 = ... # type: bool
|
||||
|
||||
PY2 = ... # type: bool
|
||||
|
||||
subversion = ... # type: List[Text]
|
||||
|
||||
text_type = ... # type: Text
|
||||
bytes_type = ... # type: ByteString
|
||||
|
||||
|
||||
def callable_check(obj: Any) -> bool: ...
|
||||
@@ -0,0 +1,125 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import os
|
||||
import re
|
||||
|
||||
from enum import IntEnum, unique
|
||||
|
||||
from pypinyin import pinyin_dict
|
||||
from pypinyin.compat import SUPPORT_UCS4
|
||||
|
||||
# 词语拼音库
|
||||
if os.environ.get('PYPINYIN_NO_PHRASES'):
|
||||
PHRASES_DICT = {}
|
||||
else:
|
||||
from pypinyin import phrases_dict
|
||||
PHRASES_DICT = phrases_dict.phrases_dict
|
||||
|
||||
# 单字拼音库
|
||||
PINYIN_DICT = pinyin_dict.pinyin_dict
|
||||
|
||||
# 利用环境变量控制不做copy操作(无自定义拼音库的情况), 以减少内存使用
|
||||
if not os.environ.get('PYPINYIN_NO_DICT_COPY'):
|
||||
PINYIN_DICT = PINYIN_DICT.copy()
|
||||
PHRASES_DICT = PHRASES_DICT.copy()
|
||||
|
||||
# 匹配使用数字标识声调的字符的正则表达式
|
||||
RE_TONE2 = re.compile(r'([aeoiuvnm])([1-4])$')
|
||||
|
||||
# 有拼音的汉字
|
||||
if SUPPORT_UCS4:
|
||||
RE_HANS = re.compile(
|
||||
r'^(?:['
|
||||
r'\u3007' # 〇
|
||||
r'\ue815-\ue864'
|
||||
r'\ufa18'
|
||||
r'\u3400-\u4dbf' # CJK扩展A:[3400-4DBF]
|
||||
r'\u4e00-\u9fff' # CJK基本:[4E00-9FFF]
|
||||
r'\uf900-\ufaff' # CJK兼容:[F900-FAFF]
|
||||
r'\U00020000-\U0002A6DF' # CJK扩展B:[20000-2A6DF]
|
||||
r'\U0002A703-\U0002B73F' # CJK扩展C:[2A700-2B73F]
|
||||
r'\U0002B740-\U0002B81D' # CJK扩展D:[2B740-2B81D]
|
||||
r'\U0002B825-\U0002BF6E' # CJK扩展E:
|
||||
r'\U0002C029-\U0002CE93' # CJK扩展F:
|
||||
r'\U0002D016'
|
||||
r'\U0002D11B-\U0002EBD9'
|
||||
r'\U0002F80A-\U0002FA1F' # CJK兼容扩展:[2F800-2FA1F]
|
||||
r'\U00030000-\U0003134A' # CJK扩展G:
|
||||
r'\U000300F7-\U00031288'
|
||||
r'\U00030EDD'
|
||||
r'\U00030EDE'
|
||||
r'\U00031350-\U00032389'
|
||||
r'])+$'
|
||||
)
|
||||
else:
|
||||
RE_HANS = re.compile(
|
||||
r'^(?:['
|
||||
r'\u3007' # 〇
|
||||
r'\ue815-\ue864'
|
||||
r'\ufa18'
|
||||
r'\u3400-\u4dbf' # CJK扩展A:[3400-4DBF]
|
||||
r'\u4e00-\u9fff' # CJK基本:[4E00-9FFF]
|
||||
r'\uf900-\ufaff' # CJK兼容:[F900-FAFF]
|
||||
r'])+$'
|
||||
)
|
||||
|
||||
|
||||
@unique
|
||||
class Style(IntEnum):
|
||||
"""拼音风格"""
|
||||
|
||||
#: 普通风格,不带声调。如: 中国 -> ``zhong guo``
|
||||
NORMAL = 0
|
||||
#: 标准声调风格,拼音声调在韵母第一个字母上(默认风格)。如: 中国 -> ``zhōng guó``
|
||||
TONE = 1
|
||||
#: 声调风格2,即拼音声调在各个韵母之后,用数字 [1-4] 进行表示。如: 中国 -> ``zho1ng guo2``
|
||||
TONE2 = 2
|
||||
#: 声调风格3,即拼音声调在各个拼音之后,用数字 [1-4] 进行表示。如: 中国 -> ``zhong1 guo2``
|
||||
TONE3 = 8
|
||||
#: 声母风格,只返回各个拼音的声母部分(注:有的拼音没有声母,详见 `#27`_)。如: 中国 -> ``zh g``
|
||||
INITIALS = 3
|
||||
#: 首字母风格,只返回拼音的首字母部分。如: 中国 -> ``z g``
|
||||
FIRST_LETTER = 4
|
||||
#: 韵母风格,只返回各个拼音的韵母部分,不带声调。如: 中国 -> ``ong uo``
|
||||
FINALS = 5
|
||||
#: 标准韵母风格,带声调,声调在韵母第一个字母上。如:中国 -> ``ōng uó``
|
||||
FINALS_TONE = 6
|
||||
#: 韵母风格2,带声调,声调在各个韵母之后,用数字 [1-4] 进行表示。如: 中国 -> ``o1ng uo2``
|
||||
FINALS_TONE2 = 7
|
||||
#: 韵母风格3,带声调,声调在各个拼音之后,用数字 [1-4] 进行表示。如: 中国 -> ``ong1 uo2``
|
||||
FINALS_TONE3 = 9
|
||||
#: 注音风格,带声调,阴平(第一声)不标。如: 中国 -> ``ㄓㄨㄥ ㄍㄨㄛˊ``
|
||||
BOPOMOFO = 10
|
||||
#: 注音风格,仅首字母。如: 中国 -> ``ㄓ ㄍ``
|
||||
BOPOMOFO_FIRST = 11
|
||||
#: 汉语拼音与俄语字母对照风格,声调在各个拼音之后,用数字 [1-4] 进行表示。如: 中国 -> ``чжун1 го2``
|
||||
CYRILLIC = 12
|
||||
#: 汉语拼音与俄语字母对照风格,仅首字母。如: 中国 -> ``ч г``
|
||||
CYRILLIC_FIRST = 13
|
||||
#: 威妥玛拼音/韦氏拼音/威式拼音风格,无声调
|
||||
WADEGILES = 14
|
||||
#: 国语罗马字风格。如:中国 -> ``jong gwo``
|
||||
GWOYEU = 15
|
||||
#: 中国内地盲文风格,无声调。如:中国 -> ``⠌⠲ ⠛⠕``
|
||||
BRAILLE_MAINLAND = 16
|
||||
#: 中国内地盲文风格,带声调。如:中国 -> ``⠌⠲⠁ ⠛⠕⠂``
|
||||
BRAILLE_MAINLAND_TONE = 17
|
||||
|
||||
|
||||
NORMAL = STYLE_NORMAL = Style.NORMAL
|
||||
TONE = STYLE_TONE = Style.TONE
|
||||
TONE2 = STYLE_TONE2 = Style.TONE2
|
||||
TONE3 = STYLE_TONE3 = Style.TONE3
|
||||
INITIALS = STYLE_INITIALS = Style.INITIALS
|
||||
FIRST_LETTER = STYLE_FIRST_LETTER = Style.FIRST_LETTER
|
||||
FINALS = STYLE_FINALS = Style.FINALS
|
||||
FINALS_TONE = STYLE_FINALS_TONE = Style.FINALS_TONE
|
||||
FINALS_TONE2 = STYLE_FINALS_TONE2 = Style.FINALS_TONE2
|
||||
FINALS_TONE3 = STYLE_FINALS_TONE3 = Style.FINALS_TONE3
|
||||
BOPOMOFO = STYLE_BOPOMOFO = Style.BOPOMOFO
|
||||
BOPOMOFO_FIRST = STYLE_BOPOMOFO_FIRST = Style.BOPOMOFO_FIRST
|
||||
CYRILLIC = STYLE_CYRILLIC = Style.CYRILLIC
|
||||
CYRILLIC_FIRST = STYLE_CYRILLIC_FIRST = Style.CYRILLIC_FIRST
|
||||
@@ -0,0 +1,78 @@
|
||||
from enum import IntEnum, unique
|
||||
from typing import Dict, List, Any, Text
|
||||
|
||||
PHRASES_DICT = ... # type: Dict[Text, List[List[Text]]]
|
||||
|
||||
PINYIN_DICT = ... # type: Dict[int, Text]
|
||||
|
||||
RE_TONE2 = ... # type: Any
|
||||
|
||||
RE_HANS = ... # type: Any
|
||||
|
||||
|
||||
@unique
|
||||
class Style(IntEnum):
|
||||
|
||||
NORMAL = ...
|
||||
|
||||
TONE = ...
|
||||
|
||||
TONE2 = ...
|
||||
|
||||
TONE3 = ...
|
||||
|
||||
INITIALS = ...
|
||||
|
||||
FIRST_LETTER = ...
|
||||
|
||||
FINALS = ...
|
||||
|
||||
FINALS_TONE = ...
|
||||
|
||||
FINALS_TONE2 = ...
|
||||
|
||||
FINALS_TONE3 = ...
|
||||
|
||||
BOPOMOFO = ...
|
||||
|
||||
BOPOMOFO_FIRST = ...
|
||||
|
||||
CYRILLIC = ...
|
||||
|
||||
CYRILLIC_FIRST = ...
|
||||
|
||||
WADEGILES = ...
|
||||
|
||||
GWOYEU = ...
|
||||
|
||||
BRAILLE_MAINLAND_TONE = ...
|
||||
BRAILLE_MAINLAND = ...
|
||||
|
||||
NORMAL = ... # type: Style
|
||||
STYLE_NORMAL = ... # type: Style
|
||||
TONE = ... # type: Style
|
||||
STYLE_TONE = ... # type: Style
|
||||
TONE2 = ... # type: Style
|
||||
STYLE_TONE2 = ... # type: Style
|
||||
TONE3 = ... # type: Style
|
||||
STYLE_TONE3 = ... # type: Style
|
||||
INITIALS = ... # type: Style
|
||||
STYLE_INITIALS = ... # type: Style
|
||||
FIRST_LETTER = ... # type: Style
|
||||
STYLE_FIRST_LETTER = ... # type: Style
|
||||
FINALS = ... # type: Style
|
||||
STYLE_FINALS = ... # type: Style
|
||||
FINALS_TONE = ... # type: Style
|
||||
STYLE_FINALS_TONE = ... # type: Style
|
||||
FINALS_TONE2 = ... # type: Style
|
||||
STYLE_FINALS_TONE2 = ... # type: Style
|
||||
FINALS_TONE3 = ... # type: Style
|
||||
STYLE_FINALS_TONE3 = ... # type: Style
|
||||
BOPOMOFO = ... # type: Style
|
||||
STYLE_BOPOMOFO = ... # type: Style
|
||||
BOPOMOFO_FIRST = ... # type: Style
|
||||
STYLE_BOPOMOFO_FIRST = ... # type: Style
|
||||
CYRILLIC = ... # type: Style
|
||||
STYLE_CYRILLIC = ... # type: Style
|
||||
CYRILLIC_FIRST = ... # type: Style
|
||||
STYLE_CYRILLIC_FIRST = ... # type: Style
|
||||
@@ -0,0 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
# 向后兼容
|
||||
from pypinyin.style._tone_rule import right_mark_index # noqa
|
||||
@@ -0,0 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from typing import Text, Optional
|
||||
|
||||
|
||||
def right_mark_index(pinyin_no_number: Text) -> Optional[int]: ...
|
||||
@@ -0,0 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""最大正向匹配分词"""
|
||||
|
||||
# 用于向后兼容,TODO: 废弃
|
||||
from pypinyin.seg.mmseg import Seg, PrefixSet, seg, retrain, p_set # noqa
|
||||
@@ -0,0 +1,29 @@
|
||||
from typing import Iterator
|
||||
from typing import Text
|
||||
|
||||
|
||||
class Seg(object):
|
||||
"""最大正向匹配分词
|
||||
|
||||
:type prefix_set: PrefixSet
|
||||
"""
|
||||
def __init__(self, prefix_set: PrefixSet) -> None: ...
|
||||
|
||||
def cut(self, text: Text) -> Iterator[Text]: ...
|
||||
|
||||
def train(self, words: Iterator[Text]) -> None: ...
|
||||
|
||||
|
||||
class PrefixSet(object):
|
||||
def __init__(self) -> None: ...
|
||||
|
||||
def train(self, word_s: Iterator[Text]) -> None: ...
|
||||
|
||||
def __contains__(self, key: Text) -> bool: ...
|
||||
|
||||
|
||||
p_set = ... # type: PrefixSet
|
||||
seg = ... # type: Seg
|
||||
|
||||
|
||||
def retrain(seg_instance: Seg) -> None: ...
|
||||
@@ -0,0 +1,73 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import re
|
||||
|
||||
from pypinyin import Style
|
||||
from pypinyin.contrib._tone_rule import right_mark_index
|
||||
|
||||
|
||||
_re_number = re.compile(r'\d')
|
||||
|
||||
|
||||
class NeutralToneWith5Mixin(object):
|
||||
"""声调使用数字表示的相关拼音风格下的结果使用 5 标识轻声。
|
||||
|
||||
使用方法::
|
||||
|
||||
from pypinyin import lazy_pinyin, Style
|
||||
from pypinyin.contrib.neutral_tone import NeutralToneWith5Mixin
|
||||
from pypinyin.converter import DefaultConverter
|
||||
from pypinyin.core import Pinyin
|
||||
|
||||
# 原来的结果中不会标识轻声
|
||||
print(lazy_pinyin('好了', style=Style.TONE2))
|
||||
# 输出: ['ha3o', 'le']
|
||||
|
||||
|
||||
class MyConverter(NeutralToneWith5Mixin, DefaultConverter):
|
||||
pass
|
||||
|
||||
my_pinyin = Pinyin(MyConverter())
|
||||
pinyin = my_pinyin.pinyin
|
||||
lazy_pinyin = my_pinyin.lazy_pinyin
|
||||
|
||||
# 新的结果中使用 ``5`` 标识轻声
|
||||
print(lazy_pinyin('好了', style=Style.TONE2))
|
||||
# 输出: ['ha3o', 'le5']
|
||||
|
||||
print(pinyin('好了', style=Style.TONE2))
|
||||
# 输出:[['ha3o'], ['le5']]
|
||||
|
||||
|
||||
"""
|
||||
|
||||
NUMBER_TONE = (Style.TONE2, Style.TONE3, Style.FINALS_TONE2,
|
||||
Style.FINALS_TONE3)
|
||||
NUMBER_AT_END = (Style.TONE3, Style.FINALS_TONE3)
|
||||
|
||||
def post_convert_style(self, han, orig_pinyin, converted_pinyin,
|
||||
style, strict, **kwargs):
|
||||
pre_data = super(NeutralToneWith5Mixin, self).post_convert_style(
|
||||
han, orig_pinyin, converted_pinyin, style, strict, **kwargs)
|
||||
|
||||
if style not in self.NUMBER_TONE:
|
||||
return pre_data
|
||||
|
||||
if pre_data is not None:
|
||||
converted_pinyin = pre_data
|
||||
if not converted_pinyin: # 空字符串
|
||||
return converted_pinyin
|
||||
# 有声调,跳过
|
||||
if _re_number.search(converted_pinyin):
|
||||
return converted_pinyin
|
||||
|
||||
if style in self.NUMBER_AT_END:
|
||||
return '{}5'.format(converted_pinyin)
|
||||
|
||||
# 找到应该在哪个字母上标声调
|
||||
mark_index = right_mark_index(converted_pinyin)
|
||||
before = converted_pinyin[:mark_index + 1]
|
||||
after = converted_pinyin[mark_index + 1:]
|
||||
|
||||
return '{}5{}'.format(before, after)
|
||||
@@ -0,0 +1,18 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from typing import Any
|
||||
from typing import Optional
|
||||
from typing import Text
|
||||
from typing import Tuple
|
||||
|
||||
from pypinyin.constants import Style
|
||||
|
||||
TStyle = Style
|
||||
|
||||
|
||||
class NeutralToneWith5Mixin(object):
|
||||
NUMBER_TONE = ... # type: Tuple[TStyle]
|
||||
NUMBER_AT_END = ... # type: Tuple[TStyle]
|
||||
|
||||
def post_convert_style(self, han: Text, orig_pinyin: Text,
|
||||
converted_pinyin: Text, style: TStyle,
|
||||
strict: bool, **kwargs: Any) -> Optional[Text]: ...
|
||||
@@ -0,0 +1,29 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from pypinyin.style._tone_convert import ( # noqa
|
||||
to_normal,
|
||||
to_tone,
|
||||
to_tone2,
|
||||
to_tone3,
|
||||
to_initials,
|
||||
to_finals,
|
||||
to_finals_tone,
|
||||
to_finals_tone2,
|
||||
to_finals_tone3,
|
||||
tone_to_normal,
|
||||
tone_to_tone2,
|
||||
tone_to_tone3,
|
||||
tone2_to_normal,
|
||||
tone2_to_tone,
|
||||
tone2_to_tone3,
|
||||
tone3_to_normal,
|
||||
tone3_to_tone,
|
||||
tone3_to_tone2,
|
||||
# 向后兼容
|
||||
_improve_tone3,
|
||||
_get_number_from_pinyin,
|
||||
_v_to_u,
|
||||
_fix_v_u,
|
||||
_re_number,
|
||||
) # noqa
|
||||
@@ -0,0 +1,51 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from typing import Any
|
||||
from typing import Optional
|
||||
from typing import Text
|
||||
from typing import Tuple
|
||||
|
||||
_re_number = ... # type: Any
|
||||
|
||||
def to_normal(pinyin: Text, v_to_u: bool = ...) -> Text: ...
|
||||
|
||||
def to_tone(pinyin: Text) -> Text: ...
|
||||
|
||||
def to_tone2(pinyin: Text, v_to_u: bool = ..., neutral_tone_with_five: bool = ...) -> Text: ...
|
||||
|
||||
def to_tone3(pinyin: Text, v_to_u: bool = ..., neutral_tone_with_five: bool = ...) -> Text: ...
|
||||
|
||||
def to_initials(pinyin: Text, strict: bool = ...) -> Text: ...
|
||||
|
||||
def to_finals(pinyin: Text, strict: bool = ..., v_to_u: bool = ...) -> Text: ...
|
||||
|
||||
def to_finals_tone(pinyin: Text, strict: bool = ...) -> Text: ...
|
||||
|
||||
def to_finals_tone2(pinyin: Text, strict: bool = ..., v_to_u: bool = ..., neutral_tone_with_five: bool = ...) -> Text: ...
|
||||
|
||||
def to_finals_tone3(pinyin: Text, strict: bool = ..., v_to_u: bool = ..., neutral_tone_with_five: bool = ...) -> Text: ...
|
||||
|
||||
def tone_to_normal(tone: Text, v_to_u: bool = ...) -> Text: ...
|
||||
|
||||
def tone_to_tone2(tone: Text, v_to_u: bool = ..., neutral_tone_with_five: bool = ...) -> Text: ...
|
||||
|
||||
def tone_to_tone3(tone: Text, v_to_u: bool = ..., neutral_tone_with_five: bool = ...) -> Text: ...
|
||||
|
||||
def tone2_to_normal(tone2: Text, v_to_u: bool = ...) -> Text: ...
|
||||
|
||||
def tone2_to_tone(tone2: Text,) -> Text: ...
|
||||
|
||||
def tone2_to_tone3(tone2: Text, v_to_u: bool = ...) -> Text: ...
|
||||
|
||||
def tone3_to_normal(tone3: Text, v_to_u: bool = ...) -> Text: ...
|
||||
|
||||
def tone3_to_tone(tone3: Text) -> Text: ...
|
||||
|
||||
def tone3_to_tone2(tone3: Text, v_to_u: bool = ...) -> Text: ...
|
||||
|
||||
def _improve_tone3(tone3: Text, neutral_tone_with_five: bool = ...) -> Text: ...
|
||||
|
||||
def _get_number_from_pinyin(pinyin: Text) -> Optional[int]: ...
|
||||
|
||||
def _v_to_u(pinyin: Text, replace: bool = ...) -> Text: ...
|
||||
|
||||
def _fix_v_u(origin_py: Text, new_py: Text, v_to_u: bool) -> Text: ...
|
||||
@@ -0,0 +1,163 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import re
|
||||
|
||||
from pypinyin.contrib.tone_convert import tone_to_tone2, tone2_to_tone
|
||||
|
||||
_re_num = re.compile(r'\d')
|
||||
|
||||
|
||||
class ToneSandhiMixin(object):
|
||||
"""
|
||||
|
||||
按普通话变调规则处理拼音:
|
||||
|
||||
* https://en.wikipedia.org/wiki/Standard_Chinese_phonology#Tone_sandhi
|
||||
* https://studycli.org/zh-CN/learn-chinese/tone-changes-in-mandarin/
|
||||
|
||||
""" # noqa
|
||||
|
||||
def post_pinyin(self, han, heteronym, pinyin_list, **kwargs):
|
||||
ret = super(ToneSandhiMixin, self).post_pinyin(
|
||||
han, heteronym, pinyin_list, **kwargs)
|
||||
if ret is not None:
|
||||
pinyin_list = ret
|
||||
|
||||
pinyin_list = self._third_tone(han, pinyin_list)
|
||||
pinyin_list = self._bu(han, pinyin_list)
|
||||
pinyin_list = self._yi(han, pinyin_list)
|
||||
|
||||
return pinyin_list
|
||||
|
||||
def _third_tone(self, han, pinyin_list):
|
||||
"""
|
||||
|
||||
Third tone sandhi:
|
||||
|
||||
The principal rule of third tone sandhi is:
|
||||
|
||||
When there are two consecutive third-tone syllables, the first of them is pronounced with second tone.
|
||||
|
||||
For example, lǎoshǔ 老鼠 ("mouse") comes to be pronounced láoshǔ [lau̯˧˥ʂu˨˩]. It has been investigated whether the rising contour (˧˥) on the prior syllable is in fact identical to a normal second tone; it has been concluded that it is, at least in terms of auditory perception.[1]: 237
|
||||
|
||||
When there are three or more third tones in a row, the situation becomes more complicated, since a third tone that precedes a second tone resulting from third tone sandhi may or may not be subject to sandhi itself. The results may depend on word boundaries, stress, and dialectal variations. General rules for three-syllable third-tone combinations can be formulated as follows:
|
||||
|
||||
If the first word is two syllables and the second word is one syllable, then the first two syllables become second tones. For example, bǎoguǎn hǎo 保管好 ("to take good care of") takes the pronunciation báoguán hǎo [pau̯˧˥kwan˧˥xau̯˨˩˦].
|
||||
If the first word is one syllable, and the second word is two syllables, the second syllable becomes second tone, but the first syllable remains third tone. For example: lǎo bǎoguǎn 老保管 ("to take care of all the time") takes the pronunciation lǎo báoguǎn [lau̯˨˩pau̯˧˥kwan˨˩˦].
|
||||
|
||||
Some linguists have put forward more comprehensive systems of sandhi rules for multiple third tone sequences. For example, it is proposed[1]: 248 that modifications are applied cyclically, initially within rhythmic feet (trochees; see below), and that sandhi "need not apply between two cyclic branches".
|
||||
|
||||
""" # noqa
|
||||
tone2_pinyin_list = [tone_to_tone2(x[0]) for x in pinyin_list]
|
||||
if '3' not in ''.join(tone2_pinyin_list):
|
||||
return pinyin_list
|
||||
|
||||
changed = False
|
||||
third_num = 0
|
||||
for pinyin in tone2_pinyin_list:
|
||||
if '3' in pinyin:
|
||||
third_num += 1
|
||||
else:
|
||||
third_num = 0
|
||||
|
||||
if third_num == 2:
|
||||
for i, v in enumerate(tone2_pinyin_list):
|
||||
if '3' in v:
|
||||
tone2_pinyin_list[i] = v.replace('3', '2')
|
||||
changed = True
|
||||
break
|
||||
|
||||
elif third_num > 2:
|
||||
n = 1
|
||||
for i, v in enumerate(tone2_pinyin_list):
|
||||
if '3' in v:
|
||||
if n == third_num:
|
||||
break
|
||||
tone2_pinyin_list[i] = v.replace('3', '2')
|
||||
changed = True
|
||||
n += 1
|
||||
|
||||
if changed:
|
||||
return [[tone2_to_tone(x)] for x in tone2_pinyin_list]
|
||||
|
||||
return pinyin_list
|
||||
|
||||
def _bu(self, han, pinyin_list):
|
||||
"""
|
||||
|
||||
For 不 bù:
|
||||
|
||||
不 is pronounced with second tone when followed by a fourth tone syllable.
|
||||
|
||||
Example: 不是 (bù+shì, "to not be") becomes búshì [pu˧˥ʂɻ̩˥˩]
|
||||
|
||||
In other cases, 不 is pronounced with fourth tone. However, when used between words in an A-not-A question, it may become neutral in tone (e.g., 是不是 shìbushì).
|
||||
|
||||
""" # noqa
|
||||
if '不' not in han:
|
||||
return pinyin_list
|
||||
|
||||
tone2_pinyin_list = [tone_to_tone2(x[0]) for x in pinyin_list]
|
||||
changed = False
|
||||
|
||||
for i, h in enumerate(han):
|
||||
current_pinyin = tone2_pinyin_list[i]
|
||||
if h == '不' and i < len(han) - 1:
|
||||
next_pinyin = tone2_pinyin_list[i+1]
|
||||
if '4' in next_pinyin:
|
||||
tone2_pinyin_list[i] = current_pinyin.replace('4', '2')
|
||||
changed = True
|
||||
else:
|
||||
tone2_pinyin_list[i] = _re_num.sub('4', current_pinyin)
|
||||
changed = True
|
||||
elif h == '不':
|
||||
tone2_pinyin_list[i] = _re_num.sub('4', current_pinyin)
|
||||
changed = True
|
||||
|
||||
if changed:
|
||||
return [[tone2_to_tone(x)] for x in tone2_pinyin_list]
|
||||
|
||||
return pinyin_list
|
||||
|
||||
def _yi(self, han, pinyin_list):
|
||||
"""
|
||||
|
||||
For 一 yī:
|
||||
|
||||
一 is pronounced with second tone when followed by a fourth tone syllable.
|
||||
|
||||
Example: 一定 (yī+dìng, "must") becomes yídìng [i˧˥tiŋ˥˩]
|
||||
|
||||
Before a first, second or third tone syllable, 一 is pronounced with fourth tone.
|
||||
|
||||
Examples:一天 (yī+tiān, "one day") becomes yìtiān [i˥˩tʰjɛn˥], 一年 (yī+nián, "one year") becomes yìnián [i˥˩njɛn˧˥], 一起 (yī+qǐ, "together") becomes yìqǐ [i˥˩t͡ɕʰi˨˩˦].
|
||||
|
||||
When final, or when it comes at the end of a multi-syllable word (regardless of the first tone of the next word), 一 is pronounced with first tone. It also has first tone when used as an ordinal number (or part of one), and when it is immediately followed by any digit (including another 一; hence both syllables of the word 一一 yīyī and its compounds have first tone).
|
||||
When 一 is used between two reduplicated words, it may become neutral in tone (e.g. 看一看 kànyikàn ("to take a look of")).
|
||||
|
||||
""" # noqa
|
||||
if '一' not in han:
|
||||
return pinyin_list
|
||||
|
||||
tone2_pinyin_list = [tone_to_tone2(x[0]) for x in pinyin_list]
|
||||
changed = False
|
||||
|
||||
for i, h in enumerate(han):
|
||||
current_pinyin = tone2_pinyin_list[i]
|
||||
if h == '一' and i < len(han) - 1:
|
||||
next_pinyin = tone2_pinyin_list[i + 1]
|
||||
if '4' in next_pinyin:
|
||||
tone2_pinyin_list[i] = current_pinyin.replace('4', '2')
|
||||
changed = True
|
||||
else:
|
||||
tone2_pinyin_list[i] = _re_num.sub('4', current_pinyin)
|
||||
changed = True
|
||||
elif h == '一':
|
||||
tone2_pinyin_list[i] = _re_num.sub('1', current_pinyin)
|
||||
changed = True
|
||||
|
||||
if changed:
|
||||
return [[tone2_to_tone(x)] for x in tone2_pinyin_list]
|
||||
|
||||
return pinyin_list
|
||||
@@ -0,0 +1,21 @@
|
||||
from typing import Any
|
||||
from typing import List
|
||||
from typing import Union
|
||||
from typing import Callable
|
||||
from typing import Optional
|
||||
from typing import Text
|
||||
|
||||
from pypinyin.constants import Style
|
||||
|
||||
|
||||
TStyle = Style
|
||||
TErrors = Union[Callable[[Text], Text], Text]
|
||||
TPinyinResult = List[List[Text]]
|
||||
TErrorResult = Union[Text, List[Text], None]
|
||||
TNoPinyinResult = Union[TPinyinResult, List[Text], Text, None]
|
||||
|
||||
class ToneSandhiMixin(object):
|
||||
|
||||
def post_pinyin(self, han: Text, heteronym: bool,
|
||||
pinyin: TPinyinResult,
|
||||
**kwargs: Any) -> Union[TPinyinResult, None]: ...
|
||||
@@ -0,0 +1,45 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
||||
class V2UMixin(object):
|
||||
"""无声调相关拼音风格下的结果使用 ``ü`` 代替原来的 ``v``
|
||||
|
||||
使用方法::
|
||||
|
||||
from pypinyin import lazy_pinyin, Style
|
||||
from pypinyin.contrib.uv import V2UMixin
|
||||
from pypinyin.converter import DefaultConverter
|
||||
from pypinyin.core import Pinyin
|
||||
|
||||
# 原来的结果中会使用 ``v`` 表示 ``ü``
|
||||
print(lazy_pinyin('战略'))
|
||||
# 输出:['zhan', 'lve']
|
||||
|
||||
|
||||
class MyConverter(V2UMixin, DefaultConverter):
|
||||
pass
|
||||
|
||||
my_pinyin = Pinyin(MyConverter())
|
||||
pinyin = my_pinyin.pinyin
|
||||
lazy_pinyin = my_pinyin.lazy_pinyin
|
||||
|
||||
# 新的结果中使用 ``ü`` 代替原来的 ``v``
|
||||
print(lazy_pinyin('战略'))
|
||||
# 输出: ['zhan', 'lüe']
|
||||
|
||||
print(pinyin('战略', style=Style.NORMAL))
|
||||
# 输出:[['zhan'], ['lüe']]
|
||||
|
||||
|
||||
"""
|
||||
|
||||
def post_convert_style(self, han, orig_pinyin, converted_pinyin,
|
||||
style, strict, **kwargs):
|
||||
pre_data = super(V2UMixin, self).post_convert_style(
|
||||
han, orig_pinyin, converted_pinyin, style, strict, **kwargs)
|
||||
|
||||
if pre_data is not None:
|
||||
converted_pinyin = pre_data
|
||||
|
||||
return converted_pinyin.replace('v', 'ü')
|
||||
@@ -0,0 +1,16 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from typing import Any
|
||||
from typing import Optional
|
||||
from typing import Text
|
||||
|
||||
from pypinyin.constants import Style
|
||||
|
||||
TStyle = Style
|
||||
|
||||
|
||||
class V2UMixin(object):
|
||||
|
||||
def post_convert_style(self, han: Text, orig_pinyin: Text,
|
||||
converted_pinyin: Text, style: TStyle,
|
||||
strict: bool, **kwargs: Any) -> Optional[Text]: ...
|
||||
@@ -0,0 +1,390 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from copy import deepcopy
|
||||
|
||||
from pypinyin.compat import text_type, callable_check
|
||||
from pypinyin.constants import (
|
||||
PHRASES_DICT, PINYIN_DICT,
|
||||
RE_HANS
|
||||
)
|
||||
from pypinyin.contrib.uv import V2UMixin
|
||||
from pypinyin.contrib.neutral_tone import NeutralToneWith5Mixin
|
||||
from pypinyin.contrib.tone_sandhi import ToneSandhiMixin
|
||||
from pypinyin.exceptions import PinyinNotFoundException
|
||||
from pypinyin.utils import _remove_dup_and_empty
|
||||
from pypinyin.style import auto_discover
|
||||
from pypinyin.style import convert as convert_style
|
||||
|
||||
auto_discover()
|
||||
|
||||
|
||||
class Converter(object):
|
||||
|
||||
def convert(self, words, style, heteronym, errors, strict, **kwargs):
|
||||
# TODO: use ``abc`` module
|
||||
raise NotImplementedError # pragma: no cover
|
||||
|
||||
|
||||
class DefaultConverter(Converter):
|
||||
def __init__(self, **kwargs):
|
||||
pass
|
||||
|
||||
def convert(self, words, style, heteronym, errors, strict, **kwargs):
|
||||
"""根据参数把汉字转成相应风格的拼音结果。
|
||||
|
||||
:param words: 汉字字符串
|
||||
:type words: unicode
|
||||
:param style: 拼音风格
|
||||
:param heteronym: 是否启用多音字
|
||||
:type heteronym: bool
|
||||
:param errors: 如何处理没有拼音的字符
|
||||
:param strict: 只获取声母或只获取韵母相关拼音风格的返回结果
|
||||
是否严格遵照《汉语拼音方案》来处理声母和韵母,
|
||||
详见 :ref:`strict`
|
||||
:type strict: bool
|
||||
:return: 按风格转换后的拼音结果
|
||||
:rtype: list
|
||||
|
||||
"""
|
||||
pys = []
|
||||
# 初步过滤没有拼音的字符
|
||||
if RE_HANS.match(words):
|
||||
pys = self._phrase_pinyin(words, style=style, heteronym=heteronym,
|
||||
errors=errors, strict=strict)
|
||||
post_data = self.post_pinyin(words, heteronym, pys)
|
||||
if post_data is not None:
|
||||
pys = post_data
|
||||
|
||||
pys = self.convert_styles(
|
||||
pys, words, style, heteronym, errors, strict)
|
||||
|
||||
else:
|
||||
py = self.handle_nopinyin(words, style=style, errors=errors,
|
||||
heteronym=heteronym, strict=strict)
|
||||
if py:
|
||||
pys.extend(py)
|
||||
|
||||
return _remove_dup_and_empty(pys)
|
||||
|
||||
def pre_convert_style(self, han, orig_pinyin, style, strict, **kwargs):
|
||||
"""在把原始带声调的拼音按拼音风格转换前会调用 ``pre_convert_style`` 方法。
|
||||
|
||||
如果返回值不为 ``None`` 会使用返回的结果代替 ``orig_pinyin``
|
||||
来进行后面的风格转换。
|
||||
|
||||
:param han: 要处理的汉字
|
||||
:param orig_pinyin: 汉字对应的原始带声调拼音
|
||||
:param style: 要转换的拼音风格
|
||||
:param strict: 只获取声母或只获取韵母相关拼音风格的返回结果
|
||||
是否严格遵照《汉语拼音方案》来处理声母和韵母,
|
||||
详见 :ref:`strict`
|
||||
:param kwargs: 其他关键字参数,暂时无用,用于以后扩展新的参数。
|
||||
:return: ``None`` 或代替 ``orig_pinyin`` 参与拼音风格转换的拼音字符串。
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
def convert_style(self, han, orig_pinyin, style, strict, **kwargs):
|
||||
"""按 ``style`` 的值对 ``orig_pinyin`` 进行处理,返回处理后的拼音
|
||||
|
||||
转换风格前会调用 ``pre_convert_style`` 方法,
|
||||
转换后会调用 ``post_convert_style`` 方法。
|
||||
|
||||
:param han: 要处理的单个汉字
|
||||
:param orig_pinyin: 汉字对应的原始带声调拼音
|
||||
:param style: 拼音风格
|
||||
:param strict: 只获取声母或只获取韵母相关拼音风格的返回结果
|
||||
是否严格遵照《汉语拼音方案》来处理声母和韵母,
|
||||
详见 :ref:`strict`
|
||||
:param kwargs: 其他关键字参数,暂时无用,用于以后扩展新的参数。
|
||||
:return: 按拼音风格转换处理后的拼音
|
||||
|
||||
"""
|
||||
pre_data = self.pre_convert_style(
|
||||
han, orig_pinyin, style=style, strict=strict)
|
||||
if pre_data is not None:
|
||||
pinyin = pre_data
|
||||
else:
|
||||
pinyin = orig_pinyin
|
||||
|
||||
converted_pinyin = self._convert_style(
|
||||
han, pinyin, style=style, strict=strict, default=pinyin)
|
||||
|
||||
post_data = self.post_convert_style(
|
||||
han, pinyin, converted_pinyin, style=style, strict=strict)
|
||||
if post_data is None:
|
||||
post_data = converted_pinyin
|
||||
|
||||
return post_data
|
||||
|
||||
def post_convert_style(self, han, orig_pinyin, converted_pinyin,
|
||||
style, strict, **kwargs):
|
||||
"""在把原始带声调的拼音按拼音风格转换前会调用 ``pre_convert_style`` 方法。
|
||||
|
||||
如果返回值不为 ``None`` 会使用返回的结果代替 ``converted_pinyin``
|
||||
作为拼音风格转换后的最终拼音结果。
|
||||
|
||||
:param han: 要处理的汉字
|
||||
:param orig_pinyin: 汉字对应的原始带声调拼音
|
||||
:param converted_pinyin: 按拼音风格转换处理后的拼音
|
||||
:param style: 要转换的拼音风格
|
||||
:param strict: 只获取声母或只获取韵母相关拼音风格的返回结果
|
||||
是否严格遵照《汉语拼音方案》来处理声母和韵母,
|
||||
详见 :ref:`strict`
|
||||
:param kwargs: 其他关键字参数,暂时无用,用于以后扩展新的参数。
|
||||
:return: ``None`` 或代替 ``converted_pinyin`` 作为拼音风格转换后的拼音结果。
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
def pre_handle_nopinyin(self, chars, style, heteronym, errors,
|
||||
strict, **kwargs):
|
||||
"""处理没有拼音的字符串前会调用 ``pre_handle_nopinyin`` 方法。
|
||||
|
||||
如果返回值不为 ``None`` 会使用返回的结果作为处理没有拼音字符串的结果,
|
||||
不再使用内置方法进行处理。
|
||||
|
||||
:param chars: 待处理的没有拼音的字符串
|
||||
:param errors: 如何处理
|
||||
:param heteronym: 是否需要处理多音字
|
||||
:param kwargs: 其他关键字参数,暂时无用,用于以后扩展新的参数。
|
||||
:return: ``None`` 或代替 ``chars`` 参与拼音风格转换的拼音字符串
|
||||
或拼音结果 list。
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
def handle_nopinyin(self, chars, style, heteronym, errors,
|
||||
strict, **kwargs):
|
||||
"""处理没有拼音的字符串。
|
||||
|
||||
处理前会调用 ``pre_handle_nopinyin`` 方法,
|
||||
处理后会调用 ``post_handle_nopinyin`` 方法。
|
||||
|
||||
:param chars: 待处理的没有拼音的字符串
|
||||
:param style: 拼音风格
|
||||
:param errors: 如何处理
|
||||
:param heteronym: 是否需要处理多音字
|
||||
:param strict: 只获取声母或只获取韵母相关拼音风格的返回结果
|
||||
是否严格遵照《汉语拼音方案》来处理声母和韵母,
|
||||
详见 :ref:`strict`
|
||||
:return: 处理后的拼音结果,如果为 ``None`` 或空 list 表示忽略这个字符串.
|
||||
:rtype: list
|
||||
"""
|
||||
pre_data = self.pre_handle_nopinyin(
|
||||
chars, style, errors=errors, heteronym=heteronym, strict=strict)
|
||||
|
||||
if pre_data is not None:
|
||||
py = pre_data
|
||||
else:
|
||||
pre_data = chars
|
||||
py = self._convert_nopinyin_chars(
|
||||
pre_data, style, errors=errors,
|
||||
heteronym=heteronym, strict=strict)
|
||||
|
||||
post_data = self.post_handle_nopinyin(
|
||||
chars, style, errors=errors, heteronym=heteronym, strict=strict,
|
||||
pinyin=py)
|
||||
if post_data is not None:
|
||||
py = post_data
|
||||
|
||||
if not py:
|
||||
return []
|
||||
if isinstance(py, list):
|
||||
# 包含多音字信息
|
||||
if isinstance(py[0], list):
|
||||
if heteronym:
|
||||
return py
|
||||
# [[a, b], [c, d]]
|
||||
# [[a], [c]]
|
||||
return [[x[0]] for x in py]
|
||||
|
||||
return [[i] for i in py]
|
||||
else:
|
||||
return [[py]]
|
||||
|
||||
def post_handle_nopinyin(self, chars, style, heteronym,
|
||||
errors, strict,
|
||||
pinyin, **kwargs):
|
||||
"""处理完没有拼音的字符串后会调用 ``post_handle_nopinyin`` 方法。
|
||||
|
||||
如果返回值不为 ``None`` 会使用返回的结果作为处理没有拼音的字符串的结果。
|
||||
|
||||
:param chars: 待处理的没有拼音的字符串
|
||||
:param errors: 如何处理
|
||||
:param heteronym: 是否需要处理多音字
|
||||
:param strict: 只获取声母或只获取韵母相关拼音风格的返回结果
|
||||
是否严格遵照《汉语拼音方案》来处理声母和韵母,
|
||||
详见 :ref:`strict`
|
||||
:param pinyin: 处理后的拼音信息,值为空 list 或包含拼音信息的 list
|
||||
:param kwargs: 其他关键字参数,暂时无用,用于以后扩展新的参数。
|
||||
:return: ``None`` 或代替 ``pinyin`` 做为处理结果。
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
def post_pinyin(self, han, heteronym, pinyin, **kwargs):
|
||||
"""找到汉字对应的拼音后,会调用 ``post_pinyin`` 方法。
|
||||
|
||||
如果返回值不为 ``None`` 会使用返回的结果作为 han 的拼音数据。
|
||||
|
||||
:param han: 单个汉字或者词语
|
||||
:param heteronym: 是否需要处理多音字
|
||||
:param pinyin: 单个汉字的拼音数据或词语的拼音数据 list
|
||||
:type pinyin: list
|
||||
:param kwargs: 其他关键字参数,暂时无用,用于以后扩展新的参数。
|
||||
:return: ``None`` 或代替 ``pinyin`` 作为 han 的拼音 list。
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
def _phrase_pinyin(self, phrase, style, heteronym, errors, strict):
|
||||
"""词语拼音转换.
|
||||
|
||||
:param phrase: 词语
|
||||
:param errors: 指定如何处理没有拼音的字符
|
||||
:param strict: 只获取声母或只获取韵母相关拼音风格的返回结果
|
||||
是否严格遵照《汉语拼音方案》来处理声母和韵母,
|
||||
详见 :ref:`strict`
|
||||
:return: 拼音列表
|
||||
:rtype: list
|
||||
"""
|
||||
pinyin_list = []
|
||||
if phrase in PHRASES_DICT:
|
||||
pinyin_list = deepcopy(PHRASES_DICT[phrase])
|
||||
else:
|
||||
for han in phrase:
|
||||
py = self._single_pinyin(han, style, heteronym, errors, strict)
|
||||
pinyin_list.extend(py)
|
||||
|
||||
return pinyin_list
|
||||
|
||||
def convert_styles(self, pinyin_list, phrase, style, heteronym, errors,
|
||||
strict, **kwargs):
|
||||
"""转换多个汉字的拼音结果的风格"""
|
||||
for idx, item in enumerate(pinyin_list):
|
||||
han = phrase[idx]
|
||||
if heteronym:
|
||||
pinyin_list[idx] = [
|
||||
self.convert_style(
|
||||
han, orig_pinyin=x, style=style, strict=strict)
|
||||
for x in item
|
||||
]
|
||||
else:
|
||||
orig_pinyin = item[0]
|
||||
pinyin_list[idx] = [
|
||||
self.convert_style(
|
||||
han, orig_pinyin=orig_pinyin, style=style,
|
||||
strict=strict)]
|
||||
|
||||
return pinyin_list
|
||||
|
||||
def _single_pinyin(self, han, style, heteronym, errors, strict):
|
||||
"""单字拼音转换.
|
||||
|
||||
:param han: 单个汉字
|
||||
:param errors: 指定如何处理没有拼音的字符,详情请参考
|
||||
:py:func:`~pypinyin.pinyin`
|
||||
:param strict: 只获取声母或只获取韵母相关拼音风格的返回结果
|
||||
是否严格遵照《汉语拼音方案》来处理声母和韵母,
|
||||
详见 :ref:`strict`
|
||||
:return: 返回拼音列表,多音字会有多个拼音项
|
||||
:rtype: list
|
||||
"""
|
||||
num = ord(han)
|
||||
# 处理没有拼音的字符
|
||||
if num not in PINYIN_DICT:
|
||||
return self.handle_nopinyin(
|
||||
han, style=style, errors=errors,
|
||||
heteronym=heteronym, strict=strict)
|
||||
|
||||
pys = PINYIN_DICT[num].split(',') # 字的拼音列表
|
||||
return [pys]
|
||||
|
||||
def _convert_style(self, han, pinyin, style, strict, default,
|
||||
**kwargs):
|
||||
if not kwargs:
|
||||
kwargs = {}
|
||||
kwargs['han'] = han
|
||||
|
||||
return convert_style(pinyin, style, strict, default=default, **kwargs)
|
||||
|
||||
def _convert_nopinyin_chars(self, chars, style, heteronym, errors, strict):
|
||||
"""转换没有拼音的字符。
|
||||
|
||||
"""
|
||||
if callable_check(errors):
|
||||
return errors(chars)
|
||||
|
||||
if errors == 'default':
|
||||
return chars
|
||||
elif errors == 'ignore':
|
||||
return None
|
||||
elif errors == 'exception':
|
||||
raise PinyinNotFoundException(chars)
|
||||
elif errors == 'replace':
|
||||
if len(chars) > 1:
|
||||
return ''.join(text_type('%x' % ord(x)) for x in chars)
|
||||
else:
|
||||
return text_type('%x' % ord(chars))
|
||||
|
||||
|
||||
class _v2UConverter(V2UMixin, DefaultConverter):
|
||||
pass
|
||||
|
||||
|
||||
class _neutralToneWith5Converter(NeutralToneWith5Mixin, DefaultConverter):
|
||||
pass
|
||||
|
||||
|
||||
class _toneSandhiConverter(ToneSandhiMixin, DefaultConverter):
|
||||
pass
|
||||
|
||||
|
||||
class UltimateConverter(DefaultConverter):
|
||||
def __init__(self, v_to_u=False, neutral_tone_with_five=False,
|
||||
tone_sandhi=False, **kwargs):
|
||||
super(UltimateConverter, self).__init__(**kwargs)
|
||||
self._v_to_u = v_to_u
|
||||
self._neutral_tone_with_five = neutral_tone_with_five
|
||||
self._tone_sandhi = tone_sandhi
|
||||
|
||||
def post_convert_style(self, han, orig_pinyin, converted_pinyin,
|
||||
style, strict, **kwargs):
|
||||
post_data = super(UltimateConverter, self).post_convert_style(
|
||||
han, orig_pinyin, converted_pinyin, style, strict, **kwargs)
|
||||
if post_data is not None:
|
||||
converted_pinyin = post_data
|
||||
|
||||
if self._v_to_u:
|
||||
post_data = _v2UConverter().post_convert_style(
|
||||
han, orig_pinyin, converted_pinyin, style, strict, **kwargs)
|
||||
if post_data is not None:
|
||||
converted_pinyin = post_data
|
||||
|
||||
if self._neutral_tone_with_five:
|
||||
post_data = _neutralToneWith5Converter().post_convert_style(
|
||||
han, orig_pinyin, converted_pinyin, style, strict, **kwargs)
|
||||
if post_data is not None:
|
||||
converted_pinyin = post_data
|
||||
|
||||
return converted_pinyin
|
||||
|
||||
def post_pinyin(self, han, heteronym, pinyin, **kwargs):
|
||||
post_data = super(UltimateConverter, self).post_pinyin(
|
||||
han, heteronym, pinyin, **kwargs)
|
||||
if post_data is not None:
|
||||
pinyin = post_data
|
||||
|
||||
if self._tone_sandhi:
|
||||
post_data = _toneSandhiConverter().post_pinyin(
|
||||
han, heteronym, pinyin, **kwargs)
|
||||
if post_data is not None:
|
||||
pinyin = post_data
|
||||
|
||||
return pinyin
|
||||
|
||||
|
||||
_mixConverter = UltimateConverter
|
||||
@@ -0,0 +1,134 @@
|
||||
from typing import Any
|
||||
from typing import List
|
||||
from typing import Union
|
||||
from typing import Callable
|
||||
from typing import Optional
|
||||
from typing import Text
|
||||
|
||||
from pypinyin.constants import Style
|
||||
|
||||
|
||||
TStyle = Style
|
||||
TErrors = Union[Callable[[Text], Text], Text]
|
||||
TPinyinResult = List[List[Text]]
|
||||
TErrorResult = Union[Text, List[Text], None]
|
||||
TNoPinyinResult = Union[TPinyinResult, List[Text], Text, None]
|
||||
|
||||
|
||||
class Converter(object):
|
||||
def convert(self, words: Text, style: TStyle, heteronym: bool,
|
||||
errors: TErrors, strict: bool = ...,
|
||||
**kwargs: Any) -> TPinyinResult: ...
|
||||
|
||||
|
||||
class DefaultConverter(Converter):
|
||||
def __init__(self, **kwargs: Any) -> None: ...
|
||||
|
||||
def convert(self, words: Text, style: TStyle, heteronym: bool,
|
||||
errors: TErrors, strict: bool = ...,
|
||||
**kwargs: Any) -> TPinyinResult: ...
|
||||
|
||||
def pre_convert_style(self, han: Text, orig_pinyin: Text, style: TStyle,
|
||||
strict: bool, **kwargs: Any) -> Optional[Text]: ...
|
||||
|
||||
def convert_style(self, han: Text, orig_pinyin: Text, style: TStyle,
|
||||
strict: bool, **kwargs: Any) -> Text: ...
|
||||
|
||||
def post_convert_style(self, han: Text, orig_pinyin: Text,
|
||||
converted_pinyin: Text, style: TStyle,
|
||||
strict: bool, **kwargs: Any) -> Optional[Text]: ...
|
||||
|
||||
def pre_handle_nopinyin(self, chars: Text, style: TStyle, heteronym: bool,
|
||||
errors: TErrors, strict: bool
|
||||
) -> TNoPinyinResult: ...
|
||||
|
||||
def handle_nopinyin(self, chars: Text, style: TStyle, heteronym: bool,
|
||||
errors: TErrors, strict: bool, **kwargs: Any
|
||||
) -> TPinyinResult: ...
|
||||
|
||||
def post_handle_nopinyin(self, chars: Text, style: Style, heteronym: bool,
|
||||
errors: TErrors, strict: bool,
|
||||
pinyin: TNoPinyinResult, **kwargs: Any
|
||||
) -> TNoPinyinResult: ...
|
||||
|
||||
def post_pinyin(self, han: Text, heteronym: bool,
|
||||
pinyin: TPinyinResult,
|
||||
**kwargs: Any) -> Union[TPinyinResult, None]: ...
|
||||
|
||||
def convert_styles(self, pinyin_list: TPinyinResult,
|
||||
phrase: Text, style: TStyle, heteronym: bool,
|
||||
errors: TErrors, strict: bool, **kwargs: Any,
|
||||
) -> TPinyinResult: ...
|
||||
|
||||
def _phrase_pinyin(self, phrase: Text, style: TStyle, heteronym: bool,
|
||||
errors: TErrors, strict: bool
|
||||
) -> TPinyinResult: ...
|
||||
|
||||
def _single_pinyin(self, han: Text, style: TStyle, heteronym: bool,
|
||||
errors: TErrors, strict: bool
|
||||
) -> TPinyinResult: ...
|
||||
|
||||
def _convert_style(self, han: Text, pinyin: Text, style: TStyle,
|
||||
strict: bool, default: Text, **kwargs: Any
|
||||
) -> Text: ...
|
||||
|
||||
def _convert_nopinyin_chars(self, chars: Text, style: TStyle,
|
||||
heteronym: bool, errors: TErrors,
|
||||
strict: bool
|
||||
) -> TNoPinyinResult: ...
|
||||
|
||||
|
||||
class UltimateConverter(DefaultConverter):
|
||||
def __init__(self, **kwargs: Any) -> None:
|
||||
self._tone_sandhi = ...
|
||||
self._neutral_tone_with_five = ...
|
||||
self._v_to_u = ...
|
||||
...
|
||||
|
||||
def convert(self, words: Text, style: TStyle, heteronym: bool,
|
||||
errors: TErrors, strict: bool = ...,
|
||||
**kwargs: Any) -> TPinyinResult: ...
|
||||
|
||||
def pre_convert_style(self, han: Text, orig_pinyin: Text, style: TStyle,
|
||||
strict: bool, **kwargs: Any) -> Optional[Text]: ...
|
||||
|
||||
def convert_style(self, han: Text, orig_pinyin: Text, style: TStyle,
|
||||
strict: bool, **kwargs: Any) -> Text: ...
|
||||
|
||||
def post_convert_style(self, han: Text, orig_pinyin: Text,
|
||||
converted_pinyin: Text, style: TStyle,
|
||||
strict: bool, **kwargs: Any) -> Optional[Text]: ...
|
||||
|
||||
def pre_handle_nopinyin(self, chars: Text, style: TStyle, heteronym: bool,
|
||||
errors: TErrors, strict: bool
|
||||
) -> TNoPinyinResult: ...
|
||||
|
||||
def handle_nopinyin(self, chars: Text, style: TStyle, heteronym: bool,
|
||||
errors: TErrors, strict: bool, **kwargs: Any
|
||||
) -> TPinyinResult: ...
|
||||
|
||||
def post_handle_nopinyin(self, chars: Text, style: Style, heteronym: bool,
|
||||
errors: TErrors, strict: bool,
|
||||
pinyin: TNoPinyinResult, **kwargs: Any
|
||||
) -> TNoPinyinResult: ...
|
||||
|
||||
def post_pinyin(self, han: Text, heteronym: bool,
|
||||
pinyin: TPinyinResult,
|
||||
**kwargs: Any) -> Union[TPinyinResult, None]: ...
|
||||
|
||||
def _phrase_pinyin(self, phrase: Text, style: TStyle, heteronym: bool,
|
||||
errors: TErrors, strict: bool
|
||||
) -> TPinyinResult: ...
|
||||
|
||||
def _single_pinyin(self, han: Text, style: TStyle, heteronym: bool,
|
||||
errors: TErrors, strict: bool
|
||||
) -> TPinyinResult: ...
|
||||
|
||||
def _convert_style(self, han: Text, pinyin: Text, style: TStyle,
|
||||
strict: bool, default: Text, **kwargs: Any
|
||||
) -> Text: ...
|
||||
|
||||
def _convert_nopinyin_chars(self, chars: Text, style: TStyle,
|
||||
heteronym: bool, errors: TErrors,
|
||||
strict: bool
|
||||
) -> TNoPinyinResult: ...
|
||||
@@ -0,0 +1,388 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from itertools import chain
|
||||
|
||||
from pypinyin.compat import text_type
|
||||
from pypinyin.constants import (
|
||||
PHRASES_DICT, PINYIN_DICT, Style, RE_HANS
|
||||
)
|
||||
from pypinyin.converter import DefaultConverter, UltimateConverter
|
||||
from pypinyin.contrib.tone_sandhi import ToneSandhiMixin
|
||||
from pypinyin.contrib.tone_convert import tone2_to_tone
|
||||
from pypinyin.seg import mmseg
|
||||
from pypinyin.seg.simpleseg import seg
|
||||
|
||||
|
||||
def load_single_dict(pinyin_dict, style='default'):
|
||||
"""载入用户自定义的单字拼音库
|
||||
|
||||
:param pinyin_dict: 单字拼音库。比如: ``{0x963F: u"ā,ē"}``
|
||||
:param style: pinyin_dict 参数值的拼音库风格. 支持 'default', 'tone2'
|
||||
:type pinyin_dict: dict
|
||||
"""
|
||||
if style == 'tone2':
|
||||
for k, v in pinyin_dict.items():
|
||||
v = tone2_to_tone(v)
|
||||
PINYIN_DICT[k] = v
|
||||
else:
|
||||
PINYIN_DICT.update(pinyin_dict)
|
||||
|
||||
mmseg.retrain(mmseg.seg)
|
||||
|
||||
|
||||
def load_phrases_dict(phrases_dict, style='default'):
|
||||
"""载入用户自定义的词语拼音库
|
||||
|
||||
:param phrases_dict: 词语拼音库。比如: ``{u"阿爸": [[u"ā"], [u"bà"]]}``
|
||||
:param style: phrases_dict 参数值的拼音库风格. 支持 'default', 'tone2'
|
||||
:type phrases_dict: dict
|
||||
"""
|
||||
if style == 'tone2':
|
||||
for k, value in phrases_dict.items():
|
||||
v = [
|
||||
list(map(tone2_to_tone, pys))
|
||||
for pys in value
|
||||
]
|
||||
PHRASES_DICT[k] = v
|
||||
else:
|
||||
PHRASES_DICT.update(phrases_dict)
|
||||
|
||||
mmseg.retrain(mmseg.seg)
|
||||
|
||||
|
||||
class Pinyin(object):
|
||||
|
||||
def __init__(self, converter=None, **kwargs):
|
||||
self._converter = converter or DefaultConverter()
|
||||
|
||||
def pinyin(self, hans, style=Style.TONE, heteronym=False,
|
||||
errors='default', strict=True, **kwargs):
|
||||
"""将汉字转换为拼音,返回汉字的拼音列表。
|
||||
|
||||
:param hans: 汉字字符串( ``'你好吗'`` )或列表( ``['你好', '吗']`` ).
|
||||
可以使用自己喜爱的分词模块对字符串进行分词处理,
|
||||
只需将经过分词处理的字符串列表传进来就可以了。
|
||||
:type hans: unicode 字符串或字符串列表
|
||||
:param style: 指定拼音风格,默认是 :py:attr:`~pypinyin.Style.TONE` 风格。
|
||||
更多拼音风格详见 :class:`~pypinyin.Style`
|
||||
:param errors: 指定如何处理没有拼音的字符。详见 :ref:`handle_no_pinyin`
|
||||
|
||||
* ``'default'``: 保留原始字符
|
||||
* ``'ignore'``: 忽略该字符
|
||||
* ``'exception'``: 抛出异常
|
||||
:class:`~pypinyin.exceptions.PinyinNotFoundException`
|
||||
* ``'replace'``: 替换为去掉 ``\\u`` 的 unicode 编码字符串
|
||||
(``'\\u90aa'`` => ``'90aa'``)
|
||||
* callable 对象: 回调函数之类的可调用对象。
|
||||
|
||||
:param heteronym: 是否启用多音字
|
||||
:param strict: 只获取声母或只获取韵母相关拼音风格的返回结果
|
||||
是否严格遵照《汉语拼音方案》来处理声母和韵母,
|
||||
详见 :ref:`strict`
|
||||
:return: 拼音列表
|
||||
:rtype: list
|
||||
|
||||
"""
|
||||
# 对字符串进行分词处理
|
||||
if isinstance(hans, text_type):
|
||||
han_list = self.seg(hans)
|
||||
else:
|
||||
if isinstance(self._converter, UltimateConverter) or \
|
||||
isinstance(self._converter, ToneSandhiMixin):
|
||||
han_list = []
|
||||
for h in hans:
|
||||
if not RE_HANS.match(h):
|
||||
han_list.extend(self.seg(h))
|
||||
else:
|
||||
han_list.append(h)
|
||||
else:
|
||||
han_list = chain(*(self.seg(x) for x in hans))
|
||||
|
||||
pys = []
|
||||
for words in han_list:
|
||||
pys.extend(
|
||||
self._converter.convert(
|
||||
words, style, heteronym, errors, strict=strict))
|
||||
return pys
|
||||
|
||||
def lazy_pinyin(self, hans, style=Style.NORMAL,
|
||||
errors='default', strict=True, **kwargs):
|
||||
"""将汉字转换为拼音,返回不包含多音字结果的拼音列表.
|
||||
|
||||
与 :py:func:`~pypinyin.pinyin` 的区别是每个汉字的拼音是个字符串,
|
||||
并且每个字只包含一个读音.
|
||||
|
||||
:param hans: 汉字字符串( ``'你好吗'`` )或列表( ``['你好', '吗']`` ).
|
||||
可以使用自己喜爱的分词模块对字符串进行分词处理,
|
||||
只需将经过分词处理的字符串列表传进来就可以了。
|
||||
:type hans: unicode 字符串或字符串列表
|
||||
:param style: 指定拼音风格,默认是 :py:attr:`~pypinyin.Style.NORMAL` 风格。
|
||||
更多拼音风格详见 :class:`~pypinyin.Style`。
|
||||
:param errors: 指定如何处理没有拼音的字符,详情请参考
|
||||
:py:func:`~pypinyin.pinyin`
|
||||
:param strict: 只获取声母或只获取韵母相关拼音风格的返回结果
|
||||
是否严格遵照《汉语拼音方案》来处理声母和韵母,
|
||||
详见 :ref:`strict`
|
||||
:return: 拼音列表(e.g. ``['zhong', 'guo', 'ren']``)
|
||||
:rtype: list
|
||||
|
||||
"""
|
||||
return list(
|
||||
chain(
|
||||
*self.pinyin(
|
||||
hans, style=style, heteronym=False,
|
||||
errors=errors, strict=strict)))
|
||||
|
||||
def pre_seg(self, hans, **kwargs):
|
||||
"""对字符串进行分词前将调用 ``pre_seg`` 方法对未分词的字符串做预处理。
|
||||
|
||||
默认原样返回传入的 ``hans``。
|
||||
|
||||
如果这个方法的返回值类型是 ``list``,表示返回的是一个分词后的结果,此时,
|
||||
``seg`` 方法中将不再调用 ``seg_function`` 进行分词。
|
||||
|
||||
:param hans: 分词前的字符串
|
||||
:return: ``None`` or ``list``
|
||||
"""
|
||||
pass
|
||||
|
||||
def seg(self, hans, **kwargs):
|
||||
"""对汉字进行分词。
|
||||
|
||||
分词前会调用 ``pre_seg`` 方法,分词后会调用 ``post_seg`` 方法。
|
||||
|
||||
:param hans:
|
||||
:return:
|
||||
"""
|
||||
pre_data = self.pre_seg(hans)
|
||||
if isinstance(pre_data, list):
|
||||
seg_data = pre_data
|
||||
else:
|
||||
seg_data = self.get_seg()(hans)
|
||||
|
||||
post_data = self.post_seg(hans, seg_data)
|
||||
if isinstance(post_data, list):
|
||||
return post_data
|
||||
|
||||
return seg_data
|
||||
|
||||
def get_seg(self, **kwargs):
|
||||
"""获取分词函数。
|
||||
|
||||
:return: 分词函数
|
||||
"""
|
||||
return seg
|
||||
|
||||
def post_seg(self, hans, seg_data, **kwargs):
|
||||
"""对字符串进行分词后将调用 ``post_seg`` 方法对分词后的结果做处理。
|
||||
|
||||
默认原样返回传入的 ``seg_data``。
|
||||
|
||||
如果这个方法的返回值类型是 ``list``,表示对分词结果做了二次处理,此时,
|
||||
``seg`` 方法将以这个返回的数据作为返回值。
|
||||
|
||||
:param hans: 分词前的字符串
|
||||
:param seg_data: 分词后的结果
|
||||
:type seg_data: list
|
||||
:return: ``None`` or ``list``
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
_default_convert = DefaultConverter()
|
||||
_default_pinyin = Pinyin(_default_convert)
|
||||
|
||||
|
||||
def to_fixed(pinyin, style, strict=True):
|
||||
# 用于向后兼容,TODO: 废弃
|
||||
return _default_convert.convert_style(
|
||||
'', pinyin, style=style, strict=strict, default=pinyin)
|
||||
|
||||
|
||||
_to_fixed = to_fixed
|
||||
|
||||
|
||||
def handle_nopinyin(chars, errors='default', heteronym=True):
|
||||
# 用于向后兼容,TODO: 废弃
|
||||
return _default_convert.handle_nopinyin(
|
||||
chars, style=None, errors=errors, heteronym=heteronym, strict=True)
|
||||
|
||||
|
||||
def single_pinyin(han, style, heteronym, errors='default', strict=True):
|
||||
# 用于向后兼容,TODO: 废弃
|
||||
return _default_convert._single_pinyin(
|
||||
han, style, heteronym, errors=errors, strict=strict)
|
||||
|
||||
|
||||
def phrase_pinyin(phrase, style, heteronym, errors='default', strict=True):
|
||||
# 用于向后兼容,TODO: 废弃
|
||||
return _default_convert._phrase_pinyin(
|
||||
phrase, style, heteronym, errors=errors, strict=strict)
|
||||
|
||||
|
||||
def pinyin(hans, style=Style.TONE, heteronym=False,
|
||||
errors='default', strict=True,
|
||||
v_to_u=False, neutral_tone_with_five=False):
|
||||
"""将汉字转换为拼音,返回汉字的拼音列表。
|
||||
|
||||
:param hans: 汉字字符串( ``'你好吗'`` )或列表( ``['你好', '吗']`` ).
|
||||
可以使用自己喜爱的分词模块对字符串进行分词处理,
|
||||
只需将经过分词处理的字符串列表传进来就可以了。
|
||||
:type hans: unicode 字符串或字符串列表
|
||||
:param style: 指定拼音风格,默认是 :py:attr:`~pypinyin.Style.TONE` 风格。
|
||||
更多拼音风格详见 :class:`~pypinyin.Style`
|
||||
:param errors: 指定如何处理没有拼音的字符。详见 :ref:`handle_no_pinyin`
|
||||
|
||||
* ``'default'``: 保留原始字符
|
||||
* ``'ignore'``: 忽略该字符
|
||||
* ``'replace'``: 替换为去掉 ``\\u`` 的 unicode 编码字符串
|
||||
(``'\\u90aa'`` => ``'90aa'``)
|
||||
* callable 对象: 回调函数之类的可调用对象。
|
||||
|
||||
:param heteronym: 是否启用多音字
|
||||
:param strict: 只获取声母或只获取韵母相关拼音风格的返回结果
|
||||
是否严格遵照《汉语拼音方案》来处理声母和韵母,
|
||||
详见 :ref:`strict`
|
||||
:param v_to_u: 无声调相关拼音风格下的结果是否使用 ``ü`` 代替原来的 ``v``
|
||||
当为 False 时结果中将使用 ``v`` 表示 ``ü``
|
||||
:type v_to_u: bool
|
||||
:param neutral_tone_with_five: 声调使用数字表示的相关拼音风格下的结果是否
|
||||
使用 5 标识轻声
|
||||
:type neutral_tone_with_five: bool
|
||||
:return: 拼音列表
|
||||
:rtype: list
|
||||
|
||||
:raise AssertionError: 当传入的字符串不是 unicode 字符时会抛出这个异常
|
||||
|
||||
Usage::
|
||||
|
||||
>>> from pypinyin import pinyin, Style
|
||||
>>> import pypinyin
|
||||
>>> pinyin('中心')
|
||||
[['zhōng'], ['xīn']]
|
||||
>>> pinyin('中心', heteronym=True) # 启用多音字模式
|
||||
[['zhōng', 'zhòng'], ['xīn']]
|
||||
>>> pinyin('中心', style=Style.FIRST_LETTER) # 设置拼音风格
|
||||
[['z'], ['x']]
|
||||
>>> pinyin('中心', style=Style.TONE2)
|
||||
[['zho1ng'], ['xi1n']]
|
||||
>>> pinyin('中心', style=Style.CYRILLIC)
|
||||
[['чжун1'], ['синь1']]
|
||||
>>> pinyin('战略', v_to_u=True, style=Style.NORMAL)
|
||||
[['zhan'], ['lüe']]
|
||||
>>> pinyin('衣裳', style=Style.TONE3, neutral_tone_with_five=True)
|
||||
[['yi1'], ['shang5']]
|
||||
"""
|
||||
_pinyin = Pinyin(UltimateConverter(
|
||||
v_to_u=v_to_u, neutral_tone_with_five=neutral_tone_with_five))
|
||||
return _pinyin.pinyin(
|
||||
hans, style=style, heteronym=heteronym, errors=errors, strict=strict)
|
||||
|
||||
|
||||
def slug(hans, style=Style.NORMAL, heteronym=False, separator='-',
|
||||
errors='default', strict=True):
|
||||
"""将汉字转换为拼音,然后生成 slug 字符串.
|
||||
|
||||
:param hans: 汉字字符串( ``'你好吗'`` )或列表( ``['你好', '吗']`` ).
|
||||
可以使用自己喜爱的分词模块对字符串进行分词处理,
|
||||
只需将经过分词处理的字符串列表传进来就可以了。
|
||||
:type hans: unicode 字符串或字符串列表
|
||||
:param style: 指定拼音风格,默认是 :py:attr:`~pypinyin.Style.NORMAL` 风格。
|
||||
更多拼音风格详见 :class:`~pypinyin.Style`
|
||||
:param heteronym: 是否启用多音字
|
||||
:param separator: 两个拼音间的分隔符/连接符
|
||||
:param errors: 指定如何处理没有拼音的字符,详情请参考
|
||||
:py:func:`~pypinyin.pinyin`
|
||||
:param strict: 只获取声母或只获取韵母相关拼音风格的返回结果
|
||||
是否严格遵照《汉语拼音方案》来处理声母和韵母,
|
||||
详见 :ref:`strict`
|
||||
:return: slug 字符串.
|
||||
|
||||
:raise AssertionError: 当传入的字符串不是 unicode 字符时会抛出这个异常
|
||||
|
||||
::
|
||||
|
||||
>>> import pypinyin
|
||||
>>> from pypinyin import Style
|
||||
>>> pypinyin.slug('中国人')
|
||||
'zhong-guo-ren'
|
||||
>>> pypinyin.slug('中国人', separator=' ')
|
||||
'zhong guo ren'
|
||||
>>> pypinyin.slug('中国人', style=Style.FIRST_LETTER)
|
||||
'z-g-r'
|
||||
>>> pypinyin.slug('中国人', style=Style.CYRILLIC)
|
||||
'чжун1-го2-жэнь2'
|
||||
"""
|
||||
return separator.join(
|
||||
chain(
|
||||
*_default_pinyin.pinyin(
|
||||
hans, style=style, heteronym=heteronym,
|
||||
errors=errors, strict=strict
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def lazy_pinyin(hans, style=Style.NORMAL, errors='default', strict=True,
|
||||
v_to_u=False, neutral_tone_with_five=False, tone_sandhi=False):
|
||||
"""将汉字转换为拼音,返回不包含多音字结果的拼音列表.
|
||||
|
||||
与 :py:func:`~pypinyin.pinyin` 的区别是返回的拼音是个字符串,
|
||||
并且每个字只包含一个读音.
|
||||
|
||||
:param hans: 汉字字符串( ``'你好吗'`` )或列表( ``['你好', '吗']`` ).
|
||||
可以使用自己喜爱的分词模块对字符串进行分词处理,
|
||||
只需将经过分词处理的字符串列表传进来就可以了。
|
||||
:type hans: unicode 字符串或字符串列表
|
||||
:param style: 指定拼音风格,默认是 :py:attr:`~pypinyin.Style.NORMAL` 风格。
|
||||
更多拼音风格详见 :class:`~pypinyin.Style`。
|
||||
:param errors: 指定如何处理没有拼音的字符,详情请参考
|
||||
:py:func:`~pypinyin.pinyin`
|
||||
:param strict: 只获取声母或只获取韵母相关拼音风格的返回结果
|
||||
是否严格遵照《汉语拼音方案》来处理声母和韵母,
|
||||
详见 :ref:`strict`
|
||||
:param v_to_u: 无声调相关拼音风格下的结果是否使用 ``ü`` 代替原来的 ``v``
|
||||
当为 False 时结果中将使用 ``v`` 表示 ``ü``
|
||||
:type v_to_u: bool
|
||||
:param neutral_tone_with_five: 声调使用数字表示的相关拼音风格下的结果是否
|
||||
使用 5 标识轻声
|
||||
:type neutral_tone_with_five: bool
|
||||
:param tone_sandhi: 是否按照声调 `变调规则 <https://en.wikipedia.org/wiki/Standard_Chinese_phonology#Tone_sandhi>`__
|
||||
对拼音进行处理
|
||||
(使用预先通过分词库进行过分词后的结果作为 ``hans``
|
||||
参数的值效果会更好,因为变调效果依赖分词效果)
|
||||
:type tone_sandhi: bool
|
||||
:return: 拼音列表(e.g. ``['zhong', 'guo', 'ren']``)
|
||||
:rtype: list
|
||||
|
||||
:raise AssertionError: 当传入的字符串不是 unicode 字符时会抛出这个异常
|
||||
|
||||
Usage::
|
||||
|
||||
>>> from pypinyin import lazy_pinyin, Style
|
||||
>>> import pypinyin
|
||||
>>> lazy_pinyin('中心')
|
||||
['zhong', 'xin']
|
||||
>>> lazy_pinyin('中心', style=Style.TONE)
|
||||
['zhōng', 'xīn']
|
||||
>>> lazy_pinyin('中心', style=Style.FIRST_LETTER)
|
||||
['z', 'x']
|
||||
>>> lazy_pinyin('中心', style=Style.TONE2)
|
||||
['zho1ng', 'xi1n']
|
||||
>>> lazy_pinyin('中心', style=Style.CYRILLIC)
|
||||
['чжун1', 'синь1']
|
||||
>>> lazy_pinyin('战略', v_to_u=True)
|
||||
['zhan', 'lüe']
|
||||
>>> lazy_pinyin('衣裳', style=Style.TONE3, neutral_tone_with_five=True)
|
||||
['yi1', 'shang5']
|
||||
>>> lazy_pinyin('你好', style=Style.TONE2, tone_sandhi=True)
|
||||
['ni2', 'ha3o']
|
||||
""" # noqa
|
||||
_pinyin = Pinyin(UltimateConverter(
|
||||
v_to_u=v_to_u, neutral_tone_with_five=neutral_tone_with_five,
|
||||
tone_sandhi=tone_sandhi))
|
||||
return _pinyin.lazy_pinyin(
|
||||
hans, style=style, errors=errors, strict=strict)
|
||||
@@ -0,0 +1,118 @@
|
||||
from typing import Any
|
||||
from typing import List
|
||||
from typing import Dict
|
||||
from typing import Union
|
||||
from typing import Callable
|
||||
from typing import Optional
|
||||
from typing import Text
|
||||
|
||||
from pypinyin.constants import Style
|
||||
from pypinyin.converter import Converter
|
||||
|
||||
|
||||
TStyle = Union[Style, Text]
|
||||
TErrors = Union[Callable[[Text], Text], Text]
|
||||
TPinyinResult = List[List[Text]]
|
||||
|
||||
|
||||
def load_single_dict(pinyin_dict: Dict[int, Text],
|
||||
style: str = ...) -> None: ...
|
||||
|
||||
|
||||
def load_phrases_dict(phrases_dict: Dict[Text, List[List[Text]]],
|
||||
style: str = ...
|
||||
) -> None: ...
|
||||
|
||||
|
||||
def to_fixed(pinyin: Text, style: TStyle,
|
||||
strict: bool = ...) -> Text: ...
|
||||
|
||||
|
||||
def _handle_nopinyin_char(chars: Text, errors: TErrors = ...
|
||||
) -> Optional[Text]: ...
|
||||
|
||||
|
||||
def handle_nopinyin(chars: Text, errors: TErrors = ..., heteronym: bool = ...
|
||||
) -> List[List[Text]]: ...
|
||||
|
||||
|
||||
def single_pinyin(han: Text, style: TStyle, heteronym: bool,
|
||||
errors: TErrors = ...,
|
||||
strict: bool = ...
|
||||
) -> List[List[Text]]: ...
|
||||
|
||||
|
||||
def phrase_pinyin(phrase: Text,
|
||||
style: TStyle,
|
||||
heteronym: bool,
|
||||
errors: TErrors = ...,
|
||||
strict: bool = ...
|
||||
) -> List[List[Text]]: ...
|
||||
|
||||
|
||||
def _pinyin(words: Text,
|
||||
style: TStyle,
|
||||
heteronym: bool,
|
||||
errors: TErrors,
|
||||
strict: bool = ...
|
||||
) -> List[List[Text]]:...
|
||||
|
||||
|
||||
def pinyin(hans: Union[List[Text], Text],
|
||||
style: TStyle = ...,
|
||||
heteronym: bool = ...,
|
||||
errors: TErrors = ...,
|
||||
strict: bool = ...,
|
||||
v_to_u: bool = ...,
|
||||
neutral_tone_with_five: bool = ...
|
||||
) -> List[List[Text]]: ...
|
||||
|
||||
|
||||
def slug(hans: Union[List[Text], Text],
|
||||
style: TStyle = ...,
|
||||
heteronym: bool = ...,
|
||||
separator: Text = ...,
|
||||
errors: TErrors = ...,
|
||||
strict: bool = ...
|
||||
) -> Text: ...
|
||||
|
||||
|
||||
def lazy_pinyin(hans: Union[List[Text], Text],
|
||||
style: TStyle = ...,
|
||||
errors: TErrors = ...,
|
||||
strict: bool = ...,
|
||||
v_to_u: bool = ...,
|
||||
neutral_tone_with_five: bool = ...,
|
||||
tone_sandhi: bool = ...
|
||||
) -> List[Text]: ...
|
||||
|
||||
|
||||
class Pinyin(object):
|
||||
|
||||
def __init__(self, converter: Converter = ..., **kwargs: Any) -> None:
|
||||
self._converter = ... # type: Converter
|
||||
|
||||
def pinyin(self, hans: Union[List[Text], Text],
|
||||
style: TStyle = ...,
|
||||
heteronym: bool = ...,
|
||||
errors: TErrors = ...,
|
||||
strict: bool = ...,
|
||||
**kwargs: Any
|
||||
) -> TPinyinResult: ...
|
||||
|
||||
def lazy_pinyin(self, hans: Union[List[Text], Text],
|
||||
style: TStyle = ...,
|
||||
errors: TErrors = ...,
|
||||
strict: bool = ...,
|
||||
**kwargs: Any
|
||||
) -> List[Text]: ...
|
||||
|
||||
def pre_seg(self, hans: Text,
|
||||
**kwargs: Any) -> Optional[List[Text]]: ...
|
||||
|
||||
def post_seg(self, hans: Text, seg_data: List[Text],
|
||||
**kwargs: Any) -> Optional[List[Text]]: ...
|
||||
|
||||
def seg(self, hans: Text, **kwargs: Any) -> List[Text]: ...
|
||||
|
||||
def get_seg(self, **kwargs: Any) -> Callable[[Text], List[Text]]: ...
|
||||
@@ -0,0 +1,14 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
||||
class PinyinNotFoundException(Exception):
|
||||
#: 异常信息
|
||||
message = ''
|
||||
#: 不包含拼音的字符串
|
||||
chars = ''
|
||||
|
||||
def __init__(self, chars):
|
||||
self.message = 'No pinyin found for character "{}"'.format(chars)
|
||||
self.chars = chars
|
||||
super(PinyinNotFoundException, self).__init__(self.message)
|
||||
@@ -0,0 +1,8 @@
|
||||
from typing import Union, Text, ByteString
|
||||
|
||||
|
||||
class PinyinNotFoundException(Exception):
|
||||
message: Union[Text, ByteString]
|
||||
chars: Union[Text, ByteString]
|
||||
|
||||
def __init__(self, chars: Union[Text, ByteString]) -> None: ...
|
||||
@@ -0,0 +1,53 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
# 带声调字符。
|
||||
phonetic_symbol = {
|
||||
"ā": "a1",
|
||||
"á": "a2",
|
||||
"ǎ": "a3",
|
||||
"à": "a4",
|
||||
|
||||
"ē": "e1",
|
||||
"é": "e2",
|
||||
"ě": "e3",
|
||||
"è": "e4",
|
||||
|
||||
"ō": "o1",
|
||||
"ó": "o2",
|
||||
"ǒ": "o3",
|
||||
"ò": "o4",
|
||||
|
||||
"ī": "i1",
|
||||
"í": "i2",
|
||||
"ǐ": "i3",
|
||||
"ì": "i4",
|
||||
|
||||
"ū": "u1",
|
||||
"ú": "u2",
|
||||
"ǔ": "u3",
|
||||
"ù": "u4",
|
||||
|
||||
# üe
|
||||
"ü": "v",
|
||||
"ǖ": "v1",
|
||||
"ǘ": "v2",
|
||||
"ǚ": "v3",
|
||||
"ǜ": "v4",
|
||||
|
||||
"ń": "n2",
|
||||
"ň": "n3",
|
||||
"ǹ": "n4",
|
||||
|
||||
"m̄": "m1", # len('m̄') == 2
|
||||
"ḿ": "m2",
|
||||
"m̀": "m4", # len("m̀") == 2
|
||||
|
||||
"ê̄": "ê1", # len('ê̄') == 2
|
||||
"ế": "ê2",
|
||||
"ê̌": "ê3", # len('ê̌') == 2
|
||||
"ề": "ê4",
|
||||
}
|
||||
phonetic_symbol_reverse = dict((v, k) for k, v in phonetic_symbol.items())
|
||||
@@ -0,0 +1,5 @@
|
||||
from typing import Dict, Text
|
||||
|
||||
|
||||
phonetic_symbol = ... # type: Dict[Text, Text]
|
||||
phonetic_symbol_reverse = ... # type: Dict[Text, Text]
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,20 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from codecs import open
|
||||
import json
|
||||
import os
|
||||
|
||||
_current_dir = os.path.dirname(os.path.realpath(__file__))
|
||||
_json_path = os.path.join(_current_dir, 'phrases_dict.json')
|
||||
|
||||
phrases_dict = {}
|
||||
|
||||
|
||||
def _load_phrases_dict():
|
||||
global phrases_dict
|
||||
with open(_json_path, encoding='utf8') as fp:
|
||||
phrases_dict = json.loads(fp.read())
|
||||
|
||||
|
||||
_load_phrases_dict()
|
||||
@@ -0,0 +1,3 @@
|
||||
from typing import Dict, List, Text
|
||||
|
||||
phrases_dict = ... # type: Dict[Text, List[List[Text]]]
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,22 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from codecs import open
|
||||
import json
|
||||
import os
|
||||
|
||||
_current_dir = os.path.dirname(os.path.realpath(__file__))
|
||||
_json_path = os.path.join(_current_dir, 'pinyin_dict.json')
|
||||
pinyin_dict = {}
|
||||
|
||||
|
||||
def _load_pinyin_dict():
|
||||
global pinyin_dict
|
||||
with open(_json_path, encoding='utf8') as fp:
|
||||
pinyin_dict = json.loads(fp.read())
|
||||
for k, v in pinyin_dict.copy().items():
|
||||
del pinyin_dict[k]
|
||||
pinyin_dict[int(k)] = v
|
||||
|
||||
|
||||
_load_pinyin_dict()
|
||||
@@ -0,0 +1,3 @@
|
||||
from typing import Dict, Text
|
||||
|
||||
pinyin_dict = ... # type: Dict[int, Text]
|
||||
@@ -0,0 +1,144 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import unicode_literals
|
||||
from argparse import ArgumentParser
|
||||
import logging
|
||||
import sys
|
||||
|
||||
import pypinyin
|
||||
from pypinyin.compat import PY2
|
||||
|
||||
style_map = {
|
||||
'NORMAL': pypinyin.Style.NORMAL,
|
||||
'zhao': pypinyin.Style.NORMAL,
|
||||
'TONE': pypinyin.Style.TONE,
|
||||
'zh4ao': pypinyin.Style.TONE,
|
||||
'TONE2': pypinyin.Style.TONE2,
|
||||
'zha4o': pypinyin.Style.TONE2,
|
||||
'TONE3': pypinyin.Style.TONE3,
|
||||
'zhao4': pypinyin.Style.TONE3,
|
||||
'INITIALS': pypinyin.Style.INITIALS,
|
||||
'zh': pypinyin.Style.INITIALS,
|
||||
'FIRST_LETTER': pypinyin.Style.FIRST_LETTER,
|
||||
'z': pypinyin.Style.FIRST_LETTER,
|
||||
'FINALS': pypinyin.Style.FINALS,
|
||||
'ao': pypinyin.Style.FINALS,
|
||||
'FINALS_TONE': pypinyin.Style.FINALS_TONE,
|
||||
'4ao': pypinyin.Style.FINALS_TONE,
|
||||
'FINALS_TONE2': pypinyin.Style.FINALS_TONE2,
|
||||
'a4o': pypinyin.Style.FINALS_TONE2,
|
||||
'FINALS_TONE3': pypinyin.Style.FINALS_TONE3,
|
||||
'ao4': pypinyin.Style.FINALS_TONE3,
|
||||
'BOPOMOFO': pypinyin.Style.BOPOMOFO,
|
||||
'BOPOMOFO_FIRST': pypinyin.Style.BOPOMOFO_FIRST,
|
||||
'CYRILLIC': pypinyin.Style.CYRILLIC,
|
||||
'CYRILLIC_FIRST': pypinyin.Style.CYRILLIC_FIRST,
|
||||
}
|
||||
func_map = {
|
||||
'pinyin': pypinyin.pinyin,
|
||||
'slug': pypinyin.slug,
|
||||
}
|
||||
default_style = 'zh4ao'
|
||||
|
||||
|
||||
class NullWriter(object):
|
||||
"""数据流黑洞,类似 linux/unix 下 /dev/null 的效果。"""
|
||||
def write(self, string):
|
||||
pass
|
||||
|
||||
|
||||
def get_parser():
|
||||
parser = ArgumentParser(description='convert chinese to pinyin.')
|
||||
parser.add_argument('-V', '--version', action='version',
|
||||
version='{0} {1}'.format(
|
||||
pypinyin.__title__, pypinyin.__version__
|
||||
))
|
||||
# 要执行的函数名称
|
||||
parser.add_argument('-f', '--func',
|
||||
help='function name (default: "pinyin")',
|
||||
choices=['pinyin', 'slug'],
|
||||
default='pinyin')
|
||||
# 拼音风格
|
||||
parser.add_argument(
|
||||
'-s', '--style',
|
||||
help='pinyin style (default: "{0}")'.format(default_style),
|
||||
choices=style_map.keys(), default=default_style
|
||||
)
|
||||
parser.add_argument('-p', '--separator',
|
||||
help='slug separator (default: "-")',
|
||||
default='-')
|
||||
parser.add_argument('-e', '--errors',
|
||||
help=('how to handle none-pinyin string'
|
||||
' (default: "default")'),
|
||||
choices=['default', 'ignore', 'replace'],
|
||||
default='default')
|
||||
# 输出多音字
|
||||
parser.add_argument('-m', '--heteronym', help='enable heteronym',
|
||||
action='store_true')
|
||||
# 要查询的汉字
|
||||
parser.add_argument('hans', nargs='+', help='chinese string')
|
||||
return parser
|
||||
|
||||
|
||||
def main():
|
||||
# 禁用除 CRITICAL 外的日志消息
|
||||
logging.disable(logging.CRITICAL)
|
||||
|
||||
# read hans from stdin
|
||||
if not sys.stdin.isatty():
|
||||
pipe_data = sys.stdin.read().strip()
|
||||
else:
|
||||
pipe_data = ''
|
||||
args = sys.argv[1:]
|
||||
if pipe_data:
|
||||
args.append(pipe_data)
|
||||
|
||||
# 获取命令行选项和参数
|
||||
parser = get_parser()
|
||||
options = parser.parse_args(args)
|
||||
if PY2:
|
||||
hans = [
|
||||
han.decode(sys.stdin.encoding or 'utf-8') for han in options.hans
|
||||
]
|
||||
else:
|
||||
hans = options.hans
|
||||
func = getattr(pypinyin, options.func)
|
||||
style = style_map[options.style]
|
||||
heteronym = options.heteronym
|
||||
separator = options.separator
|
||||
errors = options.errors
|
||||
|
||||
func_kwargs = {
|
||||
'pinyin': {'heteronym': heteronym, 'errors': errors},
|
||||
'slug': {'heteronym': heteronym, 'separator': separator,
|
||||
'errors': errors},
|
||||
}
|
||||
if PY2:
|
||||
kwargs = func_kwargs[func.func_name]
|
||||
else:
|
||||
kwargs = func_kwargs[func.__name__]
|
||||
|
||||
# 重设标准输出流和标准错误流
|
||||
# 不输出任何字符,防止污染命令行命令的输出结果
|
||||
# 其实主要是为了干掉 jieba 内的 print 语句 ;)
|
||||
sys.stdout = sys.stderr = NullWriter()
|
||||
results = [func(han, style=style, **kwargs) for han in hans]
|
||||
# 恢复默认
|
||||
sys.stdout = sys.__stdout__
|
||||
sys.stderr = sys.__stderr__
|
||||
|
||||
for result in results:
|
||||
if not result:
|
||||
print('')
|
||||
elif result and isinstance(result, (list, tuple)):
|
||||
if isinstance(result[0], (list, tuple)):
|
||||
print(' '.join([','.join(s) for s in result]))
|
||||
else:
|
||||
print(result)
|
||||
else:
|
||||
print(result)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -0,0 +1,12 @@
|
||||
from argparse import ArgumentParser
|
||||
from typing import Union, Text, ByteString
|
||||
|
||||
|
||||
class NullWriter(object):
|
||||
def write(self, string: Union[Text, ByteString]) -> None: ...
|
||||
|
||||
|
||||
def get_parser() -> ArgumentParser: ...
|
||||
|
||||
|
||||
def main() -> None: ...
|
||||
@@ -0,0 +1,133 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""最大正向匹配分词"""
|
||||
from pypinyin.constants import PHRASES_DICT
|
||||
|
||||
|
||||
class Seg(object):
|
||||
"""正向最大匹配分词
|
||||
|
||||
:type prefix_set: PrefixSet
|
||||
:param no_non_phrases: 是否严格按照词语分词,不允许把非词语的词当做词语进行分词
|
||||
:type no_non_phrases: bool
|
||||
"""
|
||||
|
||||
def __init__(self, prefix_set, no_non_phrases=False):
|
||||
self._prefix_set = prefix_set
|
||||
self._no_non_phrases = no_non_phrases
|
||||
|
||||
def cut(self, text):
|
||||
"""分词
|
||||
|
||||
:param text: 待分词的文本
|
||||
:yield: 单个词语
|
||||
"""
|
||||
remain = text
|
||||
while remain:
|
||||
matched = ''
|
||||
last_valid_word = ''
|
||||
last_valid_index = 0
|
||||
|
||||
# 一次加一个字的匹配
|
||||
for index in range(len(remain)):
|
||||
word = remain[:index + 1]
|
||||
if word in self._prefix_set:
|
||||
matched = word
|
||||
# 检查当前匹配的词是否为有效词语
|
||||
if (not self._no_non_phrases) or word in PHRASES_DICT:
|
||||
last_valid_word = word
|
||||
last_valid_index = index + 1
|
||||
else:
|
||||
# 前缀匹配失败,需要处理之前的匹配结果
|
||||
if last_valid_word:
|
||||
# 有有效词语,输出最后一个有效词语
|
||||
yield last_valid_word
|
||||
remain = remain[last_valid_index:]
|
||||
else:
|
||||
# 没有有效词语
|
||||
if self._no_non_phrases:
|
||||
# 严格模式:输出第一个字符
|
||||
yield remain[0]
|
||||
remain = remain[1:]
|
||||
else:
|
||||
# 非严格模式:输出匹配到的前缀(如果有)或第一个字符
|
||||
if matched:
|
||||
yield matched
|
||||
remain = remain[len(matched):]
|
||||
else:
|
||||
yield remain[0]
|
||||
remain = remain[1:]
|
||||
break
|
||||
else: # 整个剩余文本都能匹配前缀
|
||||
if last_valid_word:
|
||||
# 有有效词语,输出最后一个有效词语
|
||||
yield last_valid_word
|
||||
remain = remain[last_valid_index:]
|
||||
else:
|
||||
# 没有有效词语,处理剩余文本
|
||||
if self._no_non_phrases and remain not in PHRASES_DICT:
|
||||
# 严格模式且不在词典中:拆分为单字符
|
||||
for x in remain:
|
||||
yield x
|
||||
else:
|
||||
# 非严格模式或在词典中:输出整个剩余文本
|
||||
yield remain
|
||||
break
|
||||
|
||||
def train(self, words):
|
||||
"""训练分词器
|
||||
|
||||
:param words: 词语列表
|
||||
"""
|
||||
self._prefix_set.train(words)
|
||||
|
||||
|
||||
class PrefixSet(object):
|
||||
def __init__(self):
|
||||
self._set = set()
|
||||
|
||||
def train(self, word_s):
|
||||
"""更新 prefix set
|
||||
|
||||
:param word_s: 词语库列表
|
||||
:type word_s: iterable
|
||||
:return: None
|
||||
"""
|
||||
for word in word_s:
|
||||
# 把词语的每个前缀更新到 prefix_set 中
|
||||
for index in range(len(word)):
|
||||
self._set.add(word[:index + 1])
|
||||
|
||||
def __contains__(self, key):
|
||||
return key in self._set
|
||||
|
||||
|
||||
p_set = PrefixSet()
|
||||
p_set.train(PHRASES_DICT.keys())
|
||||
|
||||
#: 基于内置词库的最大正向匹配分词器。使用:
|
||||
#:
|
||||
#: .. code-block:: python
|
||||
#:
|
||||
#: >>> from pypinyin.contrib.mmseg import seg
|
||||
#: >>> text = '你好,我是中国人,我爱我的祖国'
|
||||
#: >>> seg.cut(text)
|
||||
#: <generator object Seg.cut at 0x10b2df2b0>
|
||||
#: >>> list(seg.cut(text))
|
||||
#: ['你好', ',', '我', '是', '中国人', ',', '我', '爱',
|
||||
#: '我的', '祖', '国']
|
||||
#: >>> seg.train(['祖国', '我是'])
|
||||
#: >>> list(seg.cut(text))
|
||||
#: ['你好', ',', '我是', '中国人', ',', '我', '爱',
|
||||
#: '我的', '祖国']
|
||||
#: >>>
|
||||
seg = Seg(p_set, no_non_phrases=True)
|
||||
|
||||
|
||||
def retrain(seg_instance):
|
||||
"""重新使用内置词典训练 seg_instance。
|
||||
|
||||
比如在增加自定义词语信息后需要调用这个模块重新训练分词器
|
||||
|
||||
:type seg_instance: Seg
|
||||
"""
|
||||
seg_instance.train(PHRASES_DICT.keys())
|
||||
@@ -0,0 +1,36 @@
|
||||
from typing import Iterator
|
||||
from typing import Text
|
||||
from typing import Set
|
||||
|
||||
|
||||
class Seg(object):
|
||||
"""最大正向匹配分词
|
||||
|
||||
:type prefix_set: PrefixSet
|
||||
:type no_non_phrases: bool
|
||||
"""
|
||||
def __init__(self, prefix_set: PrefixSet, no_non_phrases: bool = False) -> None:
|
||||
self._no_non_phrases = ... # type: bool
|
||||
self._prefix_set = ... # type: PrefixSet
|
||||
...
|
||||
|
||||
def cut(self, text: Text) -> Iterator[Text]: ...
|
||||
|
||||
def train(self, words: Iterator[Text]) -> None: ...
|
||||
|
||||
|
||||
class PrefixSet(object):
|
||||
def __init__(self) -> None:
|
||||
self._set = ... # type: Set[Text]
|
||||
...
|
||||
|
||||
def train(self, word_s: Iterator[Text]) -> None: ...
|
||||
|
||||
def __contains__(self, key: Text) -> bool: ...
|
||||
|
||||
|
||||
p_set = ... # type: PrefixSet
|
||||
seg = ... # type: Seg
|
||||
|
||||
|
||||
def retrain(seg_instance: Seg) -> None: ...
|
||||
@@ -0,0 +1,68 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from itertools import chain
|
||||
|
||||
from pypinyin.compat import text_type, bytes_type
|
||||
from pypinyin.constants import RE_HANS, PHRASES_DICT
|
||||
from pypinyin.seg import mmseg
|
||||
|
||||
|
||||
def seg(hans):
|
||||
hans = simple_seg(hans)
|
||||
ret = []
|
||||
for x in hans:
|
||||
if not RE_HANS.match(x): # 没有拼音的字符,不再参与二次分词
|
||||
ret.append(x)
|
||||
elif PHRASES_DICT:
|
||||
ret.extend(list(mmseg.seg.cut(x)))
|
||||
else: # 禁用了词语库,不分词
|
||||
ret.append(x)
|
||||
return ret
|
||||
|
||||
|
||||
def simple_seg(hans):
|
||||
"""将传入的字符串按是否是汉字来分割"""
|
||||
assert not isinstance(hans, bytes_type), \
|
||||
'must be unicode string or [unicode, ...] list'
|
||||
|
||||
if isinstance(hans, text_type):
|
||||
return _seg(hans)
|
||||
else:
|
||||
hans = list(hans)
|
||||
if len(hans) == 1:
|
||||
return simple_seg(hans[0])
|
||||
return list(chain(*[simple_seg(x) for x in hans]))
|
||||
|
||||
|
||||
def _seg(chars):
|
||||
"""按是否是汉字进行分词"""
|
||||
s = '' # 保存一个词
|
||||
ret = [] # 分词结果
|
||||
flag = 0 # 上一个字符是什么? 0: 汉字, 1: 不是汉字
|
||||
|
||||
for n, c in enumerate(chars):
|
||||
if RE_HANS.match(c): # 汉字, 确定 flag 的初始值
|
||||
if n == 0: # 第一个字符
|
||||
flag = 0
|
||||
|
||||
if flag == 0:
|
||||
s += c
|
||||
else: # 上一个字符不是汉字, 分词
|
||||
ret.append(s)
|
||||
flag = 0
|
||||
s = c
|
||||
|
||||
else: # 不是汉字
|
||||
if n == 0: # 第一个字符, 确定 flag 的初始值
|
||||
flag = 1
|
||||
|
||||
if flag == 1:
|
||||
s += c
|
||||
else: # 上一个字符是汉字, 分词
|
||||
ret.append(s)
|
||||
flag = 1
|
||||
s = c
|
||||
|
||||
ret.append(s) # 最后的词
|
||||
return ret
|
||||
@@ -0,0 +1,11 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from typing import List, Text
|
||||
|
||||
|
||||
def seg(hans: Text) -> List[Text]: ...
|
||||
|
||||
|
||||
def simple_seg(hans: Text) -> List[Text]: ...
|
||||
|
||||
|
||||
def _seg(chars: Text) -> List[Text]: ...
|
||||
@@ -0,0 +1,161 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
处理汉语拼音方案中的一些特殊情况
|
||||
|
||||
|
||||
汉语拼音方案:
|
||||
|
||||
* 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
|
||||
""" # noqa
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import re
|
||||
|
||||
from pypinyin.style._constants import _FINALS
|
||||
|
||||
# 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):
|
||||
"""零声母转换,还原原始的韵母
|
||||
|
||||
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(晕);ü上两点省略。
|
||||
"""
|
||||
raw_pinyin = pinyin
|
||||
# y: yu -> v, yi -> i, y -> i
|
||||
if raw_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
|
||||
|
||||
# w: wu -> u, w -> u
|
||||
if raw_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:]
|
||||
|
||||
# 确保不会出现韵母表中不存在的韵母
|
||||
if pinyin not in _FINALS:
|
||||
return raw_pinyin
|
||||
|
||||
return pinyin
|
||||
|
||||
|
||||
def convert_uv(pinyin):
|
||||
"""ü 转换,还原原始的韵母
|
||||
|
||||
ü行的韵跟声母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):
|
||||
"""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):
|
||||
"""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):
|
||||
"""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):
|
||||
"""还原原始的韵母"""
|
||||
pinyin = convert_zero_consonant(pinyin)
|
||||
pinyin = convert_uv(pinyin)
|
||||
pinyin = convert_iou(pinyin)
|
||||
pinyin = convert_uei(pinyin)
|
||||
pinyin = convert_uen(pinyin)
|
||||
return pinyin
|
||||
@@ -0,0 +1,18 @@
|
||||
from typing import Text
|
||||
|
||||
def convert_zero_consonant(pinyin: Text) -> Text: ...
|
||||
|
||||
|
||||
def convert_uv(pinyin: Text) -> Text: ...
|
||||
|
||||
|
||||
def convert_iou(pinyin: Text) -> Text: ...
|
||||
|
||||
|
||||
def convert_uei(pinyin: Text) -> Text: ...
|
||||
|
||||
|
||||
def convert_uen(pinyin: Text) -> Text: ...
|
||||
|
||||
|
||||
def convert_finals(pinyin: Text) -> Text: ...
|
||||
@@ -0,0 +1,75 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from functools import wraps
|
||||
|
||||
# 存储各拼音风格对应的实现
|
||||
_registry = {}
|
||||
|
||||
|
||||
def convert(pinyin, style, strict, default=None, **kwargs):
|
||||
"""根据拼音风格把原始拼音转换为不同的格式
|
||||
|
||||
:param pinyin: 原始有声调的单个拼音
|
||||
:type pinyin: unicode
|
||||
:param style: 拼音风格
|
||||
:param strict: 只获取声母或只获取韵母相关拼音风格的返回结果
|
||||
是否严格遵照《汉语拼音方案》来处理声母和韵母,
|
||||
详见 :ref:`strict`
|
||||
:type strict: bool
|
||||
:param default: 拼音风格对应的实现不存在时返回的默认值
|
||||
:param kwargs: 兼容后续可能会新增的关键字参数。当前包含如下关键字参数:
|
||||
``han``: 当前拼音对应的原始汉字。
|
||||
|
||||
:return: 按照拼音风格进行处理过后的拼音字符串
|
||||
:rtype: unicode
|
||||
"""
|
||||
if style in _registry:
|
||||
return _registry[style](pinyin, strict=strict, **kwargs)
|
||||
return default
|
||||
|
||||
|
||||
def register(style, func=None):
|
||||
"""注册一个拼音风格实现。
|
||||
自定义的函数应当使用 ``**kwargs`` 来兼容后续可能会新增的关键字参数,
|
||||
当前默认会传递如下参数:
|
||||
|
||||
* ``pinyin``: 原始有声调的单个拼音
|
||||
* ``strict``: 是否开启 strict 模式
|
||||
* ``han``: 当前拼音对应的原始汉字
|
||||
|
||||
::
|
||||
|
||||
@register('echo')
|
||||
def echo(pinyin, **kwargs):
|
||||
return pinyin
|
||||
|
||||
# or
|
||||
register('echo', echo)
|
||||
"""
|
||||
if func is not None:
|
||||
_registry[style] = func
|
||||
return
|
||||
|
||||
def decorator(func):
|
||||
_registry[style] = func
|
||||
|
||||
@wraps(func)
|
||||
def wrapper(pinyin, **kwargs):
|
||||
return func(pinyin, **kwargs)
|
||||
|
||||
return wrapper
|
||||
return decorator
|
||||
|
||||
|
||||
def auto_discover():
|
||||
"""自动注册内置的拼音风格实现"""
|
||||
from pypinyin.style import ( # noqa
|
||||
initials,
|
||||
tone,
|
||||
finals,
|
||||
bopomofo,
|
||||
cyrillic,
|
||||
wadegiles,
|
||||
others,
|
||||
gwoyeu,
|
||||
braille_mainland,
|
||||
)
|
||||
@@ -0,0 +1,20 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from typing import Any, Optional, Callable, Dict, Text, Union
|
||||
|
||||
from pypinyin.constants import Style
|
||||
|
||||
TStyle = Style
|
||||
TRegisterFunc = Optional[Callable[[Text, Dict[Any, Any]], Text]]
|
||||
TWrapperFunc = Optional[Callable[[Text, Dict[Any, Any]], Text]]
|
||||
|
||||
_registry = {} # type: Dict[Union[TStyle, int, str, Any], TRegisterFunc]
|
||||
|
||||
|
||||
def convert(pinyin: Text, style: TStyle, strict: bool,
|
||||
default: Optional[Text] = ..., **kwargs: Any) -> Text: ...
|
||||
|
||||
|
||||
def register(style: Union[TStyle, int, str, Any],
|
||||
func: TRegisterFunc = ...) -> TWrapperFunc: ...
|
||||
|
||||
def auto_discover() -> None: ...
|
||||
@@ -0,0 +1,96 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
import re
|
||||
|
||||
from pypinyin import phonetic_symbol
|
||||
|
||||
# 声母表
|
||||
_INITIALS = [
|
||||
'b',
|
||||
'p',
|
||||
'm',
|
||||
'f',
|
||||
'd',
|
||||
't',
|
||||
'n',
|
||||
'l',
|
||||
'g',
|
||||
'k',
|
||||
'h',
|
||||
'j',
|
||||
'q',
|
||||
'x',
|
||||
'zh',
|
||||
'ch',
|
||||
'sh',
|
||||
'r',
|
||||
'z',
|
||||
'c',
|
||||
's',
|
||||
]
|
||||
# 声母表, 把 y, w 也当作声母
|
||||
_INITIALS_NOT_STRICT = _INITIALS + ['y', 'w']
|
||||
|
||||
# 韵母表
|
||||
_FINALS = [
|
||||
'i',
|
||||
'u',
|
||||
'ü',
|
||||
'a',
|
||||
'ia',
|
||||
'ua',
|
||||
'o',
|
||||
'uo',
|
||||
'e',
|
||||
'ie',
|
||||
'üe',
|
||||
'ai',
|
||||
'uai',
|
||||
'ei',
|
||||
'uei',
|
||||
'ao',
|
||||
'iao',
|
||||
'ou',
|
||||
'iou',
|
||||
'an',
|
||||
'ian',
|
||||
'uan',
|
||||
'üan',
|
||||
'en',
|
||||
'in',
|
||||
'uen',
|
||||
'ün',
|
||||
'ang',
|
||||
'iang',
|
||||
'uang',
|
||||
'eng',
|
||||
'ing',
|
||||
'ueng',
|
||||
'ong',
|
||||
'iong',
|
||||
|
||||
'er',
|
||||
'ê',
|
||||
]
|
||||
|
||||
# 带声调字符与数字表示声调的对应关系
|
||||
PHONETIC_SYMBOL_DICT = phonetic_symbol.phonetic_symbol.copy()
|
||||
PHONETIC_SYMBOL_DICT_KEY_LENGTH_NOT_ONE = dict(
|
||||
(k, v)
|
||||
for k, v in PHONETIC_SYMBOL_DICT.items()
|
||||
if len(k) > 1
|
||||
)
|
||||
# 匹配带声调字符的正则表达式
|
||||
RE_PHONETIC_SYMBOL = re.compile(
|
||||
r'[{0}]'.format(
|
||||
re.escape(''.join(x for x in PHONETIC_SYMBOL_DICT if len(x) == 1))
|
||||
)
|
||||
)
|
||||
|
||||
# 匹配使用数字标识声调的字符的正则表达式
|
||||
RE_TONE2 = re.compile(r'([aeoiuvnmêü])([1-5])$')
|
||||
# 匹配 TONE2 中标识韵母声调的正则表达式
|
||||
RE_TONE3 = re.compile(r'^([a-zêü]+)([1-5])([a-zêü]*)$')
|
||||
|
||||
# 匹配单个数字
|
||||
RE_NUMBER = re.compile(r'\d')
|
||||
@@ -0,0 +1,22 @@
|
||||
from typing import Any, List, Dict, Text
|
||||
|
||||
|
||||
_INITIALS = ... # type: List[Text]
|
||||
|
||||
_INITIALS_NOT_STRICT = ... # type: List[Text]
|
||||
|
||||
_FINALS = ... # type: List[Text]
|
||||
|
||||
|
||||
PHONETIC_SYMBOL_DICT = ... # type: Dict[Text, Text]
|
||||
PHONETIC_SYMBOL_DICT_KEY_LENGTH_NOT_ONE = ... # type: Dict[Text, Text]
|
||||
|
||||
RE_PHONETIC_SYMBOL = ... # type : Any
|
||||
|
||||
|
||||
RE_TONE2 = ... # type : Any
|
||||
|
||||
RE_TONE3 = ... # type : Any
|
||||
|
||||
|
||||
RE_NUMBER = ... # type: Any
|
||||
@@ -0,0 +1,577 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
import re
|
||||
|
||||
from pypinyin import phonetic_symbol
|
||||
from pypinyin.style._tone_rule import right_mark_index
|
||||
from pypinyin.style._constants import RE_TONE3, RE_TONE2
|
||||
from pypinyin.style.tone import converter
|
||||
from pypinyin.style._utils import (
|
||||
get_initials, replace_symbol_to_no_symbol,
|
||||
get_finals, replace_symbol_to_number
|
||||
)
|
||||
|
||||
_re_number = re.compile(r'\d')
|
||||
|
||||
|
||||
def to_normal(pinyin, v_to_u=False):
|
||||
"""将 :py:attr:`~pypinyin.Style.TONE`、
|
||||
:py:attr:`~pypinyin.Style.TONE2` 或
|
||||
:py:attr:`~pypinyin.Style.TONE3` 风格的拼音转换为
|
||||
:py:attr:`~pypinyin.Style.NORMAL` 风格的拼音
|
||||
|
||||
:param pinyin: :py:attr:`~pypinyin.Style.TONE`、
|
||||
:py:attr:`~pypinyin.Style.TONE2` 或
|
||||
:py:attr:`~pypinyin.Style.TONE3` 风格的拼音
|
||||
:param v_to_u: 是否使用 ``ü`` 代替原来的 ``v``,
|
||||
当为 False 时结果中将使用 ``v`` 表示 ``ü``
|
||||
:return: :py:attr:`~pypinyin.Style.NORMAL` 风格的拼音
|
||||
|
||||
Usage::
|
||||
|
||||
>>> from pypinyin.contrib.tone_convert import to_normal
|
||||
>>> to_normal('zhōng')
|
||||
'zhong'
|
||||
>>> to_normal('zho1ng')
|
||||
'zhong'
|
||||
>>> to_normal('zhong1')
|
||||
'zhong'
|
||||
>>> to_normal('lüè')
|
||||
'lve'
|
||||
>>> to_normal('lüè', v_to_u=True)
|
||||
'lüe'
|
||||
"""
|
||||
s = tone_to_tone2(pinyin, v_to_u=True)
|
||||
s = tone2_to_normal(s)
|
||||
return _fix_v_u(pinyin, s, v_to_u=v_to_u)
|
||||
|
||||
|
||||
def to_tone(pinyin):
|
||||
"""将 :py:attr:`~pypinyin.Style.TONE2` 或
|
||||
:py:attr:`~pypinyin.Style.TONE3` 风格的拼音转换为
|
||||
:py:attr:`~pypinyin.Style.TONE` 风格的拼音
|
||||
|
||||
:param pinyin: :py:attr:`~pypinyin.Style.TONE2` 或
|
||||
:py:attr:`~pypinyin.Style.TONE3` 风格的拼音
|
||||
:return: :py:attr:`~pypinyin.Style.TONE` 风格的拼音
|
||||
|
||||
Usage::
|
||||
|
||||
>>> from pypinyin.contrib.tone_convert import to_tone
|
||||
>>> to_tone('zho1ng')
|
||||
'zhōng'
|
||||
>>> to_tone('zhong1')
|
||||
'zhōng'
|
||||
"""
|
||||
pinyin = pinyin.replace('v', 'ü')
|
||||
if not _re_number.search(pinyin):
|
||||
return pinyin
|
||||
|
||||
s = tone_to_tone2(pinyin)
|
||||
s = tone2_to_tone(s)
|
||||
return s
|
||||
|
||||
|
||||
def to_tone2(pinyin, v_to_u=False, neutral_tone_with_five=False, **kwargs):
|
||||
"""将 :py:attr:`~pypinyin.Style.TONE` 或
|
||||
:py:attr:`~pypinyin.Style.TONE3` 风格的拼音转换为
|
||||
:py:attr:`~pypinyin.Style.TONE2` 风格的拼音
|
||||
|
||||
:param pinyin: :py:attr:`~pypinyin.Style.TONE` 或
|
||||
:py:attr:`~pypinyin.Style.TONE3` 风格的拼音
|
||||
:param v_to_u: 是否使用 ``ü`` 代替原来的 ``v``,
|
||||
当为 False 时结果中将使用 ``v`` 表示 ``ü``
|
||||
:param neutral_tone_with_five: 是否使用 ``5`` 标识轻声
|
||||
:param kwargs: 用于兼容老版本的 ``neutral_tone_with_5`` 参数,当传入
|
||||
``neutral_tone_with_5`` 参数时,
|
||||
将覆盖 ``neutral_tone_with_five`` 的值。
|
||||
:return: :py:attr:`~pypinyin.Style.TONE2` 风格的拼音
|
||||
|
||||
Usage::
|
||||
|
||||
>>> from pypinyin.contrib.tone_convert import to_tone2
|
||||
>>> to_tone2('zhōng')
|
||||
'zho1ng'
|
||||
>>> to_tone2('zhong1')
|
||||
'zho1ng'
|
||||
>>> to_tone2('shang')
|
||||
'shang'
|
||||
>>> to_tone2('shang', neutral_tone_with_five=True)
|
||||
'sha5ng'
|
||||
>>> to_tone2('lüè')
|
||||
'lve4'
|
||||
>>> to_tone2('lüè', v_to_u=True)
|
||||
'lüe4'
|
||||
"""
|
||||
if kwargs.get('neutral_tone_with_5', None) is not None:
|
||||
neutral_tone_with_five = kwargs['neutral_tone_with_5']
|
||||
pinyin = pinyin.replace('5', '')
|
||||
s = tone_to_tone3(
|
||||
pinyin, v_to_u=True, neutral_tone_with_five=neutral_tone_with_five)
|
||||
s = tone3_to_tone2(s)
|
||||
return _fix_v_u(pinyin, s, v_to_u)
|
||||
|
||||
|
||||
def to_tone3(pinyin, v_to_u=False, neutral_tone_with_five=False, **kwargs):
|
||||
"""将 :py:attr:`~pypinyin.Style.TONE` 或
|
||||
:py:attr:`~pypinyin.Style.TONE2` 风格的拼音转换为
|
||||
:py:attr:`~pypinyin.Style.TONE3` 风格的拼音
|
||||
|
||||
:param pinyin: :py:attr:`~pypinyin.Style.TONE` 或
|
||||
:py:attr:`~pypinyin.Style.TONE2` 风格的拼音
|
||||
:param v_to_u: 是否使用 ``ü`` 代替原来的 ``v``,
|
||||
当为 False 时结果中将使用 ``v`` 表示 ``ü``
|
||||
:param neutral_tone_with_five: 是否使用 ``5`` 标识轻声
|
||||
:param kwargs: 用于兼容老版本的 ``neutral_tone_with_5`` 参数,当传入
|
||||
``neutral_tone_with_5`` 参数时,
|
||||
将覆盖 ``neutral_tone_with_five`` 的值。
|
||||
:return: :py:attr:`~pypinyin.Style.TONE2` 风格的拼音
|
||||
|
||||
Usage::
|
||||
|
||||
>>> from pypinyin.contrib.tone_convert import to_tone3
|
||||
>>> to_tone3('zhōng')
|
||||
'zhong1'
|
||||
>>> to_tone3('zho1ng')
|
||||
'zhong1'
|
||||
>>> to_tone3('shang')
|
||||
'shang'
|
||||
>>> to_tone3('shang', neutral_tone_with_five=True)
|
||||
'shang5'
|
||||
>>> to_tone3('lüè')
|
||||
'lve4'
|
||||
>>> to_tone3('lüè', v_to_u=True)
|
||||
'lüe4'
|
||||
"""
|
||||
if kwargs.get('neutral_tone_with_5', None) is not None:
|
||||
neutral_tone_with_five = kwargs['neutral_tone_with_5']
|
||||
pinyin = pinyin.replace('5', '')
|
||||
s = tone_to_tone2(
|
||||
pinyin, v_to_u=True, neutral_tone_with_five=neutral_tone_with_five)
|
||||
s = tone2_to_tone3(s)
|
||||
return _fix_v_u(pinyin, s, v_to_u)
|
||||
|
||||
|
||||
def to_initials(pinyin, strict=True):
|
||||
"""将 :py:attr:`~pypinyin.Style.TONE`、
|
||||
:py:attr:`~pypinyin.Style.TONE2` 、
|
||||
:py:attr:`~pypinyin.Style.TONE3` 或
|
||||
:py:attr:`~pypinyin.Style.NORMAL` 风格的拼音转换为
|
||||
:py:attr:`~pypinyin.Style.INITIALS` 风格的拼音
|
||||
|
||||
:param pinyin: :py:attr:`~pypinyin.Style.TONE`、
|
||||
:py:attr:`~pypinyin.Style.TONE2` 、
|
||||
:py:attr:`~pypinyin.Style.TONE3` 或
|
||||
:py:attr:`~pypinyin.Style.NORMAL` 风格的拼音
|
||||
:param strict: 返回结果是否严格遵照《汉语拼音方案》来处理声母和韵母,
|
||||
详见 :ref:`strict`
|
||||
:return: :py:attr:`~pypinyin.Style.INITIALS` 风格的拼音
|
||||
|
||||
Usage::
|
||||
|
||||
>>> from pypinyin.contrib.tone_convert import to_initials
|
||||
>>> to_initials('zhōng')
|
||||
'zh'
|
||||
|
||||
"""
|
||||
return get_initials(pinyin, strict=strict)
|
||||
|
||||
|
||||
def to_finals(pinyin, strict=True, v_to_u=False):
|
||||
"""将 :py:attr:`~pypinyin.Style.TONE`、
|
||||
:py:attr:`~pypinyin.Style.TONE2` 、
|
||||
:py:attr:`~pypinyin.Style.TONE3` 或
|
||||
:py:attr:`~pypinyin.Style.NORMAL` 风格的拼音转换为
|
||||
:py:attr:`~pypinyin.Style.FINALS` 风格的拼音
|
||||
|
||||
:param pinyin: :py:attr:`~pypinyin.Style.TONE`、
|
||||
:py:attr:`~pypinyin.Style.TONE2` 、
|
||||
:py:attr:`~pypinyin.Style.TONE3` 或
|
||||
:py:attr:`~pypinyin.Style.NORMAL` 风格的拼音
|
||||
:param strict: 返回结果是否严格遵照《汉语拼音方案》来处理声母和韵母,
|
||||
详见 :ref:`strict`
|
||||
:param v_to_u: 是否使用 ``ü`` 代替原来的 ``v``,
|
||||
当为 False 时结果中将使用 ``v`` 表示 ``ü``
|
||||
:return: :py:attr:`~pypinyin.Style.FINALS` 风格的拼音
|
||||
|
||||
Usage::
|
||||
|
||||
>>> from pypinyin.contrib.tone_convert import to_finals
|
||||
>>> to_finals('zhōng')
|
||||
'ong'
|
||||
|
||||
"""
|
||||
new_pinyin = replace_symbol_to_no_symbol(pinyin).replace('v', 'ü')
|
||||
finals = get_finals(new_pinyin, strict=strict)
|
||||
finals = _fix_v_u(finals, finals, v_to_u)
|
||||
return finals
|
||||
|
||||
|
||||
def to_finals_tone(pinyin, strict=True):
|
||||
"""将 :py:attr:`~pypinyin.Style.TONE`、
|
||||
:py:attr:`~pypinyin.Style.TONE2` 或
|
||||
:py:attr:`~pypinyin.Style.TONE3` 风格的拼音转换为
|
||||
:py:attr:`~pypinyin.Style.FINALS_TONE` 风格的拼音
|
||||
|
||||
:param pinyin: :py:attr:`~pypinyin.Style.TONE`、
|
||||
:py:attr:`~pypinyin.Style.TONE2` 或
|
||||
:py:attr:`~pypinyin.Style.TONE3` 风格的拼音
|
||||
:param strict: 返回结果是否严格遵照《汉语拼音方案》来处理声母和韵母,
|
||||
详见 :ref:`strict`
|
||||
:return: :py:attr:`~pypinyin.Style.FINALS_TONE` 风格的拼音
|
||||
|
||||
Usage::
|
||||
|
||||
>>> from pypinyin.contrib.tone_convert import to_finals_tone
|
||||
>>> to_finals_tone('zhōng')
|
||||
'ōng'
|
||||
|
||||
"""
|
||||
finals = to_finals_tone2(pinyin, strict=strict)
|
||||
|
||||
finals = tone2_to_tone(finals)
|
||||
|
||||
return finals
|
||||
|
||||
|
||||
def to_finals_tone2(pinyin, strict=True, v_to_u=False,
|
||||
neutral_tone_with_five=False):
|
||||
"""将 :py:attr:`~pypinyin.Style.TONE`、
|
||||
:py:attr:`~pypinyin.Style.TONE2` 或
|
||||
:py:attr:`~pypinyin.Style.TONE3` 风格的拼音转换为
|
||||
:py:attr:`~pypinyin.Style.FINALS_TONE2` 风格的拼音
|
||||
|
||||
:param pinyin: :py:attr:`~pypinyin.Style.TONE`、
|
||||
:py:attr:`~pypinyin.Style.TONE2` 或
|
||||
:py:attr:`~pypinyin.Style.TONE3` 风格的拼音
|
||||
:param strict: 返回结果是否严格遵照《汉语拼音方案》来处理声母和韵母,
|
||||
详见 :ref:`strict`
|
||||
:param v_to_u: 是否使用 ``ü`` 代替原来的 ``v``,
|
||||
当为 False 时结果中将使用 ``v`` 表示 ``ü``
|
||||
:param neutral_tone_with_five: 是否使用 ``5`` 标识轻声
|
||||
:return: :py:attr:`~pypinyin.Style.FINALS_TONE2` 风格的拼音
|
||||
|
||||
Usage::
|
||||
|
||||
>>> from pypinyin.contrib.tone_convert import to_finals_tone2
|
||||
>>> to_finals_tone2('zhōng')
|
||||
'o1ng'
|
||||
|
||||
"""
|
||||
pinyin = pinyin.replace('5', '')
|
||||
finals = to_finals_tone3(pinyin, strict=strict, v_to_u=v_to_u,
|
||||
neutral_tone_with_five=neutral_tone_with_five)
|
||||
|
||||
finals = tone3_to_tone2(finals, v_to_u=v_to_u)
|
||||
|
||||
return finals
|
||||
|
||||
|
||||
def to_finals_tone3(pinyin, strict=True, v_to_u=False,
|
||||
neutral_tone_with_five=False):
|
||||
"""将 :py:attr:`~pypinyin.Style.TONE`、
|
||||
:py:attr:`~pypinyin.Style.TONE2` 或
|
||||
:py:attr:`~pypinyin.Style.TONE3` 风格的拼音转换为
|
||||
:py:attr:`~pypinyin.Style.FINALS_TONE3` 风格的拼音
|
||||
|
||||
:param pinyin: :py:attr:`~pypinyin.Style.TONE`、
|
||||
:py:attr:`~pypinyin.Style.TONE2` 或
|
||||
:py:attr:`~pypinyin.Style.TONE3` 风格的拼音
|
||||
:param strict: 返回结果是否严格遵照《汉语拼音方案》来处理声母和韵母,
|
||||
详见 :ref:`strict`
|
||||
:param v_to_u: 是否使用 ``ü`` 代替原来的 ``v``,
|
||||
当为 False 时结果中将使用 ``v`` 表示 ``ü``
|
||||
:param neutral_tone_with_five: 是否使用 ``5`` 标识轻声
|
||||
:return: :py:attr:`~pypinyin.Style.FINALS_TONE3` 风格的拼音
|
||||
|
||||
Usage::
|
||||
|
||||
>>> from pypinyin.contrib.tone_convert import to_finals_tone3
|
||||
>>> to_finals_tone3('zhōng')
|
||||
'ong1'
|
||||
|
||||
"""
|
||||
pinyin = pinyin.replace('5', '')
|
||||
finals = to_finals(pinyin, strict=strict, v_to_u=v_to_u)
|
||||
if not finals:
|
||||
return finals
|
||||
|
||||
numbers = _re_number.findall(replace_symbol_to_number(pinyin))
|
||||
if not numbers:
|
||||
if neutral_tone_with_five:
|
||||
numbers = ['5']
|
||||
else:
|
||||
return finals
|
||||
|
||||
number = numbers[0]
|
||||
finals = finals + number
|
||||
|
||||
return finals
|
||||
|
||||
|
||||
def tone_to_normal(tone, v_to_u=False):
|
||||
"""将 :py:attr:`~pypinyin.Style.TONE` 风格的拼音转换为
|
||||
:py:attr:`~pypinyin.Style.NORMAL` 风格的拼音
|
||||
|
||||
:param tone: :py:attr:`~pypinyin.Style.TONE` 风格的拼音
|
||||
:param v_to_u: 是否使用 ``ü`` 代替原来的 ``v``,
|
||||
当为 False 时结果中将使用 ``v`` 表示 ``ü``
|
||||
:return: :py:attr:`~pypinyin.Style.NORMAL` 风格的拼音
|
||||
|
||||
Usage::
|
||||
|
||||
>>> from pypinyin.contrib.tone_convert import tone_to_normal
|
||||
>>> tone_to_normal('zhōng')
|
||||
'zhong'
|
||||
>>> tone_to_normal('lüè')
|
||||
'lve'
|
||||
>>> tone_to_normal('lüè', v_to_u=True)
|
||||
'lüe'
|
||||
"""
|
||||
s = tone_to_tone2(tone, v_to_u=v_to_u)
|
||||
s = _re_number.sub('', s)
|
||||
return _v_to_u(s, v_to_u)
|
||||
|
||||
|
||||
def tone_to_tone2(tone, v_to_u=False, neutral_tone_with_five=False, **kwargs):
|
||||
"""将 :py:attr:`~pypinyin.Style.TONE` 风格的拼音转换为
|
||||
:py:attr:`~pypinyin.Style.TONE2` 风格的拼音
|
||||
|
||||
:param tone: :py:attr:`~pypinyin.Style.TONE` 风格的拼音
|
||||
:param v_to_u: 是否使用 ``ü`` 代替原来的 ``v``,
|
||||
当为 False 时结果中将使用 ``v`` 表示 ``ü``
|
||||
:param neutral_tone_with_five: 是否使用 ``5`` 标识轻声
|
||||
:param kwargs: 用于兼容老版本的 ``neutral_tone_with_5`` 参数,当传入
|
||||
``neutral_tone_with_5`` 参数时,
|
||||
将覆盖 ``neutral_tone_with_five`` 的值。
|
||||
:return: :py:attr:`~pypinyin.Style.TONE2` 风格的拼音
|
||||
|
||||
Usage::
|
||||
|
||||
>>> from pypinyin.contrib.tone_convert import tone_to_tone2
|
||||
>>> tone_to_tone2('zhōng')
|
||||
'zho1ng'
|
||||
>>> tone_to_tone2('shang')
|
||||
'shang'
|
||||
>>> tone_to_tone2('shang', neutral_tone_with_5=True)
|
||||
'sha5ng'
|
||||
>>> tone_to_tone2('lüè')
|
||||
'lve4'
|
||||
>>> tone_to_tone2('lüè', v_to_u=True)
|
||||
'lüe4'
|
||||
"""
|
||||
if kwargs.get('neutral_tone_with_5', None) is not None:
|
||||
neutral_tone_with_five = kwargs['neutral_tone_with_5']
|
||||
tone3 = tone_to_tone3(
|
||||
tone, v_to_u=v_to_u, neutral_tone_with_five=neutral_tone_with_five)
|
||||
s = tone3_to_tone2(tone3)
|
||||
return _v_to_u(s, v_to_u)
|
||||
|
||||
|
||||
def tone_to_tone3(tone, v_to_u=False, neutral_tone_with_five=False, **kwargs):
|
||||
"""将 :py:attr:`~pypinyin.Style.TONE` 风格的拼音转换为
|
||||
:py:attr:`~pypinyin.Style.TONE3` 风格的拼音
|
||||
|
||||
:param tone: :py:attr:`~pypinyin.Style.TONE` 风格的拼音
|
||||
:param v_to_u: 是否使用 ``ü`` 代替原来的 ``v``,
|
||||
当为 False 时结果中将使用 ``v`` 表示 ``ü``
|
||||
:param neutral_tone_with_five: 是否使用 ``5`` 标识轻声
|
||||
:param kwargs: 用于兼容老版本的 ``neutral_tone_with_5`` 参数,当传入
|
||||
``neutral_tone_with_5`` 参数时,
|
||||
将覆盖 ``neutral_tone_with_five`` 的值。
|
||||
:return: :py:attr:`~pypinyin.Style.TONE3` 风格的拼音
|
||||
|
||||
Usage::
|
||||
|
||||
>>> from pypinyin.contrib.tone_convert import tone_to_tone3
|
||||
>>> tone_to_tone3('zhōng')
|
||||
'zhong1'
|
||||
>>> tone_to_tone3('shang')
|
||||
'shang'
|
||||
>>> tone_to_tone3('shang', neutral_tone_with_five=True)
|
||||
'shang5'
|
||||
>>> tone_to_tone3('lüè')
|
||||
'lve4'
|
||||
>>> tone_to_tone3('lüè', v_to_u=True)
|
||||
'lüe4'
|
||||
"""
|
||||
if kwargs.get('neutral_tone_with_5', None) is not None:
|
||||
neutral_tone_with_five = kwargs['neutral_tone_with_5']
|
||||
tone3 = converter.to_tone3(tone)
|
||||
s = _improve_tone3(tone3, neutral_tone_with_five=neutral_tone_with_five)
|
||||
return _v_to_u(s, v_to_u)
|
||||
|
||||
|
||||
def tone2_to_normal(tone2, v_to_u=False):
|
||||
"""将 :py:attr:`~pypinyin.Style.TONE2` 风格的拼音转换为
|
||||
:py:attr:`~pypinyin.Style.NORMAL` 风格的拼音
|
||||
|
||||
:param tone2: :py:attr:`~pypinyin.Style.TONE2` 风格的拼音
|
||||
:param v_to_u: 是否使用 ``ü`` 代替原来的 ``v``,
|
||||
当为 False 时结果中将使用 ``v`` 表示 ``ü``
|
||||
:return: Style.NORMAL 风格的拼音
|
||||
|
||||
Usage::
|
||||
|
||||
>>> from pypinyin.contrib.tone_convert import tone2_to_normal
|
||||
>>> tone2_to_normal('zho1ng')
|
||||
'zhong'
|
||||
>>> tone2_to_normal('lüe4')
|
||||
'lve'
|
||||
>>> tone2_to_normal('lüe4', v_to_u=True)
|
||||
'lüe'
|
||||
"""
|
||||
s = _re_number.sub('', tone2)
|
||||
s = _v_to_u(s, v_to_u)
|
||||
return _fix_v_u(tone2, s, v_to_u=v_to_u)
|
||||
|
||||
|
||||
def tone2_to_tone(tone2):
|
||||
"""将 :py:attr:`~pypinyin.Style.TONE2` 风格的拼音转换为
|
||||
:py:attr:`~pypinyin.Style.TONE` 风格的拼音
|
||||
|
||||
:param tone2: :py:attr:`~pypinyin.Style.TONE2` 风格的拼音
|
||||
:return: Style.TONE 风格的拼音
|
||||
|
||||
Usage::
|
||||
|
||||
>>> from pypinyin.contrib.tone_convert import tone2_to_tone
|
||||
>>> tone2_to_tone('zho1ng')
|
||||
'zhōng'
|
||||
"""
|
||||
regex = re.compile(RE_TONE2.pattern.replace('$', ''))
|
||||
d = phonetic_symbol.phonetic_symbol_reverse
|
||||
string = tone2.replace('ü', 'v').replace('5', '').replace('0', '')
|
||||
|
||||
def _replace(m):
|
||||
s = m.group(0)
|
||||
return d.get(s) or s
|
||||
|
||||
return regex.sub(_replace, string).replace('v', 'ü')
|
||||
|
||||
|
||||
def tone2_to_tone3(tone2, v_to_u=False):
|
||||
"""将 :py:attr:`~pypinyin.Style.TONE2` 风格的拼音转换为
|
||||
:py:attr:`~pypinyin.Style.TONE3` 风格的拼音
|
||||
|
||||
:param tone2: :py:attr:`~pypinyin.Style.TONE2` 风格的拼音
|
||||
:param v_to_u: 是否使用 ``ü`` 代替原来的 ``v``,
|
||||
当为 False 时结果中将使用 ``v`` 表示 ``ü``
|
||||
:return: :py:attr:`~pypinyin.Style.TONE3` 风格的拼音
|
||||
|
||||
Usage::
|
||||
|
||||
>>> from pypinyin.contrib.tone_convert import tone2_to_tone3
|
||||
>>> tone2_to_tone3('zho1ng')
|
||||
'zhong1'
|
||||
>>> tone2_to_tone3('lüe4')
|
||||
'lve4'
|
||||
>>> tone2_to_tone3('lüe4', v_to_u=True)
|
||||
'lüe4'
|
||||
"""
|
||||
tone3 = RE_TONE3.sub(r'\1\3\2', tone2)
|
||||
return _fix_v_u(tone2, tone3, v_to_u=v_to_u)
|
||||
|
||||
|
||||
def tone3_to_normal(tone3, v_to_u=False):
|
||||
"""将 :py:attr:`~pypinyin.Style.TONE3` 风格的拼音转换为
|
||||
:py:attr:`~pypinyin.Style.NORMAL` 风格的拼音
|
||||
|
||||
:param tone3: :py:attr:`~pypinyin.Style.TONE3` 风格的拼音
|
||||
:param v_to_u: 是否使用 ``ü`` 代替原来的 ``v``,
|
||||
当为 False 时结果中将使用 ``v`` 表示 ``ü``
|
||||
:return: :py:attr:`~pypinyin.Style.NORMAL` 风格的拼音
|
||||
|
||||
Usage::
|
||||
|
||||
>>> from pypinyin.contrib.tone_convert import tone3_to_normal
|
||||
>>> tone3_to_normal('zhong1')
|
||||
'zhong'
|
||||
>>> tone3_to_normal('lüe4')
|
||||
'lve'
|
||||
>>> tone3_to_normal('lüe4', v_to_u=True)
|
||||
'lüe'
|
||||
"""
|
||||
s = _re_number.sub('', tone3)
|
||||
s = _v_to_u(s, v_to_u)
|
||||
return _fix_v_u(tone3, s, v_to_u=v_to_u)
|
||||
|
||||
|
||||
def tone3_to_tone(tone3):
|
||||
"""将 :py:attr:`~pypinyin.Style.TONE3` 风格的拼音转换为
|
||||
:py:attr:`~pypinyin.Style.TONE` 风格的拼音
|
||||
|
||||
:param tone3: :py:attr:`~pypinyin.Style.TONE3` 风格的拼音
|
||||
:return: :py:attr:`~pypinyin.Style.TONE` 风格的拼音
|
||||
|
||||
Usage::
|
||||
|
||||
>>> from pypinyin.contrib.tone_convert import tone3_to_tone
|
||||
>>> tone3_to_tone('zhong1')
|
||||
'zhōng'
|
||||
"""
|
||||
tone2 = tone3_to_tone2(tone3, v_to_u=True)
|
||||
return tone2_to_tone(tone2)
|
||||
|
||||
|
||||
def tone3_to_tone2(tone3, v_to_u=False):
|
||||
"""将 :py:attr:`~pypinyin.Style.TONE3` 风格的拼音转换为
|
||||
:py:attr:`~pypinyin.Style.TONE2` 风格的拼音
|
||||
|
||||
:param tone3: :py:attr:`~pypinyin.Style.TONE3` 风格的拼音
|
||||
:param v_to_u: 是否使用 ``ü`` 代替原来的 ``v``,
|
||||
当为 False 时结果中将使用 ``v`` 表示 ``ü``
|
||||
:return: :py:attr:`~pypinyin.Style.TONE2` 风格的拼音
|
||||
|
||||
Usage::
|
||||
|
||||
>>> from pypinyin.contrib.tone_convert import tone3_to_tone2
|
||||
>>> tone3_to_tone2('zhong1')
|
||||
'zho1ng'
|
||||
>>> tone3_to_tone2('lüe4')
|
||||
'lve4'
|
||||
>>> tone3_to_tone2('lüe4', v_to_u=True)
|
||||
'lüe4'
|
||||
"""
|
||||
no_number_tone3 = tone3_to_normal(tone3)
|
||||
mark_index = right_mark_index(no_number_tone3)
|
||||
if mark_index is None:
|
||||
mark_index = len(no_number_tone3) - 1
|
||||
before = no_number_tone3[:mark_index + 1]
|
||||
after = no_number_tone3[mark_index + 1:]
|
||||
|
||||
number = _get_number_from_pinyin(tone3)
|
||||
if number is None:
|
||||
return tone3
|
||||
|
||||
s = '{}{}{}'.format(before, number, after)
|
||||
return _fix_v_u(tone3, s, v_to_u=v_to_u)
|
||||
|
||||
|
||||
def _improve_tone3(tone3, neutral_tone_with_five=False):
|
||||
number = _get_number_from_pinyin(tone3)
|
||||
if number is None and neutral_tone_with_five and tone3 != '':
|
||||
tone3 = '{}5'.format(tone3)
|
||||
return tone3
|
||||
|
||||
|
||||
def _get_number_from_pinyin(pinyin):
|
||||
numbers = _re_number.findall(pinyin)
|
||||
if numbers:
|
||||
number = numbers[0]
|
||||
else:
|
||||
number = None
|
||||
return number
|
||||
|
||||
|
||||
def _v_to_u(pinyin, replace=False):
|
||||
if not replace:
|
||||
return pinyin
|
||||
return pinyin.replace('v', 'ü')
|
||||
|
||||
|
||||
def _fix_v_u(origin_py, new_py, v_to_u):
|
||||
if not v_to_u:
|
||||
return new_py.replace('ü', 'v')
|
||||
|
||||
return _v_to_u(new_py, replace=True)
|
||||
@@ -0,0 +1,51 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from typing import Any
|
||||
from typing import Optional
|
||||
from typing import Text
|
||||
from typing import Tuple
|
||||
|
||||
_re_number = ... # type: Any
|
||||
|
||||
def to_normal(pinyin: Text, v_to_u: bool = ...) -> Text: ...
|
||||
|
||||
def to_tone(pinyin: Text) -> Text: ...
|
||||
|
||||
def to_tone2(pinyin: Text, v_to_u: bool = ..., neutral_tone_with_five: bool = ...) -> Text: ...
|
||||
|
||||
def to_tone3(pinyin: Text, v_to_u: bool = ..., neutral_tone_with_five: bool = ...) -> Text: ...
|
||||
|
||||
def to_initials(pinyin: Text, strict: bool = ...) -> Text: ...
|
||||
|
||||
def to_finals(pinyin: Text, strict: bool = ..., v_to_u: bool = ...) -> Text: ...
|
||||
|
||||
def to_finals_tone(pinyin: Text, strict: bool = ...) -> Text: ...
|
||||
|
||||
def to_finals_tone2(pinyin: Text, strict: bool = ..., v_to_u: bool = ..., neutral_tone_with_five: bool = ...) -> Text: ...
|
||||
|
||||
def to_finals_tone3(pinyin: Text, strict: bool = ..., v_to_u: bool = ..., neutral_tone_with_five: bool = ...) -> Text: ...
|
||||
|
||||
def tone_to_normal(tone: Text, v_to_u: bool = ...) -> Text: ...
|
||||
|
||||
def tone_to_tone2(tone: Text, v_to_u: bool = ..., neutral_tone_with_five: bool = ...) -> Text: ...
|
||||
|
||||
def tone_to_tone3(tone: Text, v_to_u: bool = ..., neutral_tone_with_five: bool = ...) -> Text: ...
|
||||
|
||||
def tone2_to_normal(tone2: Text, v_to_u: bool = ...) -> Text: ...
|
||||
|
||||
def tone2_to_tone(tone2: Text) -> Text: ...
|
||||
|
||||
def tone2_to_tone3(tone2: Text, v_to_u: bool = ...) -> Text: ...
|
||||
|
||||
def tone3_to_normal(tone3: Text, v_to_u: bool = ...) -> Text: ...
|
||||
|
||||
def tone3_to_tone(tone3: Text) -> Text: ...
|
||||
|
||||
def tone3_to_tone2(tone3: Text, v_to_u: bool = ...) -> Text: ...
|
||||
|
||||
def _improve_tone3(tone3: Text, neutral_tone_with_five: bool = ...) -> Text: ...
|
||||
|
||||
def _get_number_from_pinyin(pinyin: Text) -> Optional[int]: ...
|
||||
|
||||
def _v_to_u(pinyin: Text, replace: bool = ...) -> Text: ...
|
||||
|
||||
def _fix_v_u(origin_py: Text, new_py: Text, v_to_u: bool) -> Text: ...
|
||||
@@ -0,0 +1,58 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
"""
|
||||
标调位置
|
||||
|
||||
有 ɑ 不放过,
|
||||
|
||||
没 ɑ 找 o、e;
|
||||
|
||||
ɑ、o、e、i、u、ü
|
||||
|
||||
标调就按这顺序;
|
||||
|
||||
i、u 若是连在一起,
|
||||
|
||||
谁在后面就标谁。
|
||||
|
||||
http://www.hwjyw.com/resource/content/2010/06/04/8183.shtml
|
||||
https://www.zhihu.com/question/23655297
|
||||
https://github.com/mozillazg/python-pinyin/issues/160
|
||||
http://www.pinyin.info/rules/where.html
|
||||
"""
|
||||
|
||||
# TODO: 增加测试用例:使用 pinyin_dict 中的数据收集所有带声调拼音测试这个规则的正确性
|
||||
# 1. 收集所有带声调拼音
|
||||
# 2. 转换为数字声调拼音(tone3),然后再转换为声调拼音
|
||||
# 3. 比对转换后的声调拼音跟原始拼音,确保结果一致
|
||||
|
||||
|
||||
def right_mark_index(pinyin_no_tone):
|
||||
# 'iou', 'uei', 'uen': 还原原始韵母后,还需要按照还原前的声调进行标记
|
||||
if 'iou' in pinyin_no_tone:
|
||||
return pinyin_no_tone.index('u')
|
||||
if 'uei' in pinyin_no_tone:
|
||||
return pinyin_no_tone.index('i')
|
||||
if 'uen' in pinyin_no_tone:
|
||||
return pinyin_no_tone.index('u')
|
||||
|
||||
# 有 ɑ 不放过, 没 ɑ 找 o、e
|
||||
for c in ['a', 'o', 'e']:
|
||||
if c in pinyin_no_tone:
|
||||
return pinyin_no_tone.index(c) + len(c) - 1
|
||||
|
||||
# i、u 若是连在一起,谁在后面就标谁
|
||||
for c in ['iu', 'ui']:
|
||||
if c in pinyin_no_tone:
|
||||
return pinyin_no_tone.index(c) + len(c) - 1
|
||||
|
||||
# ɑ、o、e、i、u、ü
|
||||
for c in ['i', 'u', 'v', 'ü']:
|
||||
if c in pinyin_no_tone:
|
||||
return pinyin_no_tone.index(c) + len(c) - 1
|
||||
|
||||
# n, m, ê
|
||||
for c in ['n', 'm', 'ê']:
|
||||
if c in pinyin_no_tone:
|
||||
return pinyin_no_tone.index(c) + len(c) - 1
|
||||
@@ -0,0 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from typing import Text, Optional
|
||||
|
||||
|
||||
def right_mark_index(pinyin_no_number: Text) -> Optional[int]: ...
|
||||
@@ -0,0 +1,94 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from pypinyin.standard import convert_finals
|
||||
from pypinyin.style._constants import (
|
||||
_INITIALS, _INITIALS_NOT_STRICT, _FINALS,
|
||||
RE_PHONETIC_SYMBOL, PHONETIC_SYMBOL_DICT,
|
||||
PHONETIC_SYMBOL_DICT_KEY_LENGTH_NOT_ONE,
|
||||
RE_NUMBER
|
||||
)
|
||||
|
||||
|
||||
def get_initials(pinyin, strict):
|
||||
"""获取单个拼音中的声母.
|
||||
|
||||
:param pinyin: 单个拼音
|
||||
:type pinyin: unicode
|
||||
:param strict: 是否严格遵照《汉语拼音方案》来处理声母和韵母
|
||||
:return: 声母
|
||||
:rtype: unicode
|
||||
"""
|
||||
if strict:
|
||||
_initials = _INITIALS
|
||||
else:
|
||||
_initials = _INITIALS_NOT_STRICT
|
||||
|
||||
for i in _initials:
|
||||
if pinyin.startswith(i):
|
||||
return i
|
||||
return ''
|
||||
|
||||
|
||||
def get_finals(pinyin, strict):
|
||||
"""获取单个拼音中的韵母.
|
||||
|
||||
:param pinyin: 单个拼音,无声调拼音
|
||||
:type pinyin: unicode
|
||||
:param strict: 是否严格遵照《汉语拼音方案》来处理声母和韵母
|
||||
:return: 韵母
|
||||
:rtype: unicode
|
||||
"""
|
||||
if strict:
|
||||
pinyin = convert_finals(pinyin)
|
||||
|
||||
initials = get_initials(pinyin, strict=strict) or ''
|
||||
|
||||
# 按声母分割,剩下的就是韵母
|
||||
finals = pinyin[len(initials):]
|
||||
|
||||
# 处理既没有声母也没有韵母的情况
|
||||
if strict and finals not in _FINALS:
|
||||
# 处理 y, w 导致误判的问题,比如 yo
|
||||
initials = get_initials(pinyin, strict=False)
|
||||
finals = pinyin[len(initials):]
|
||||
if finals in _FINALS:
|
||||
return finals
|
||||
return ''
|
||||
|
||||
# ń, ḿ
|
||||
if not finals and not strict:
|
||||
return pinyin
|
||||
|
||||
return finals
|
||||
|
||||
|
||||
def replace_symbol_to_number(pinyin):
|
||||
"""把声调替换为数字"""
|
||||
def _replace(match):
|
||||
symbol = match.group(0) # 带声调的字符
|
||||
# 返回使用数字标识声调的字符
|
||||
return PHONETIC_SYMBOL_DICT[symbol]
|
||||
|
||||
# 替换拼音中的带声调字符
|
||||
value = RE_PHONETIC_SYMBOL.sub(_replace, pinyin)
|
||||
for symbol, to in PHONETIC_SYMBOL_DICT_KEY_LENGTH_NOT_ONE.items():
|
||||
value = value.replace(symbol, to)
|
||||
|
||||
return value
|
||||
|
||||
|
||||
def replace_symbol_to_no_symbol(pinyin):
|
||||
"""把带声调字符替换为没有声调的字符"""
|
||||
value = replace_symbol_to_number(pinyin)
|
||||
return RE_NUMBER.sub('', value)
|
||||
|
||||
|
||||
def has_finals(pinyin):
|
||||
"""判断是否有韵母"""
|
||||
# 鼻音: 'm̄', 'ḿ', 'm̀', 'ń', 'ň', 'ǹ ' 没有韵母
|
||||
for symbol in ['m̄', 'ḿ', 'm̀', 'ń', 'ň', 'ǹ']:
|
||||
if symbol in pinyin:
|
||||
return False
|
||||
|
||||
return True
|
||||
@@ -0,0 +1,15 @@
|
||||
from typing import Text
|
||||
|
||||
def get_initials(pinyin: Text, strict: bool) -> Text: ...
|
||||
|
||||
|
||||
def get_finals(pinyin: Text, strict: bool) -> Text: ...
|
||||
|
||||
|
||||
def replace_symbol_to_number(pinyin: Text) -> Text: ...
|
||||
|
||||
|
||||
def replace_symbol_to_no_symbol(pinyin: Text) -> Text: ...
|
||||
|
||||
|
||||
def has_finals(pinyin: Text) -> bool: ...
|
||||
@@ -0,0 +1,74 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""BOPOMOFO 相关的几个拼音风格实现:
|
||||
|
||||
Style.BOPOMOFO
|
||||
Style.BOPOMOFO_FIRST
|
||||
"""
|
||||
from __future__ import unicode_literals
|
||||
import re
|
||||
|
||||
from pypinyin.constants import Style
|
||||
from pypinyin.style import register
|
||||
from pypinyin.style._constants import RE_TONE3
|
||||
from pypinyin.style._utils import replace_symbol_to_number
|
||||
|
||||
# 注音转换表
|
||||
BOPOMOFO_REPLACE = (
|
||||
(re.compile(r'^m(\d)$'), 'mu\\1'), # 呣
|
||||
(re.compile(r'^n(\d)$'), 'N\\1'), # 嗯
|
||||
(re.compile(r'^r5$'), 'er5'), # 〜兒
|
||||
(re.compile(r'iu'), 'iou'),
|
||||
(re.compile(r'ui'), 'uei'),
|
||||
(re.compile(r'ong'), 'ung'),
|
||||
(re.compile(r'^yi?'), 'i'),
|
||||
(re.compile(r'^wu?'), 'u'),
|
||||
(re.compile(r'iu'), 'v'),
|
||||
(re.compile(r'^([jqx])u'), '\\1v'),
|
||||
(re.compile(r'([iuv])n'), '\\1en'),
|
||||
(re.compile(r'^zhi?'), 'Z'),
|
||||
(re.compile(r'^chi?'), 'C'),
|
||||
(re.compile(r'^shi?'), 'S'),
|
||||
(re.compile(r'^([zcsr])i'), '\\1'),
|
||||
(re.compile(r'ai'), 'A'),
|
||||
(re.compile(r'ei'), 'I'),
|
||||
(re.compile(r'ao'), 'O'),
|
||||
(re.compile(r'ou'), 'U'),
|
||||
(re.compile(r'ang'), 'K'),
|
||||
(re.compile(r'eng'), 'G'),
|
||||
(re.compile(r'an'), 'M'),
|
||||
(re.compile(r'en'), 'N'),
|
||||
(re.compile(r'er'), 'R'),
|
||||
(re.compile(r'eh'), 'E'),
|
||||
(re.compile(r'([iv])e'), '\\1E'),
|
||||
(re.compile(r'([^0-4])$'), '\\g<1>0'),
|
||||
(re.compile(r'1$'), ''),
|
||||
)
|
||||
BOPOMOFO_TABLE = dict(zip(
|
||||
'bpmfdtnlgkhjqxZCSrzcsiuvaoeEAIOUMNKGR2340ê',
|
||||
'ㄅㄆㄇㄈㄉㄊㄋㄌㄍㄎㄏㄐㄑㄒㄓㄔㄕㄖㄗㄘㄙㄧㄨㄩㄚㄛㄜㄝㄞㄟㄠㄡㄢㄣㄤㄥㄦˊˇˋ˙ㄝ'
|
||||
))
|
||||
|
||||
|
||||
class BopomofoConverter(object):
|
||||
def to_bopomofo(self, pinyin, **kwargs):
|
||||
pinyin = self._pre_convert(pinyin)
|
||||
# 查表替换成注音
|
||||
for find_re, replace in BOPOMOFO_REPLACE:
|
||||
pinyin = find_re.sub(replace, pinyin)
|
||||
pinyin = ''.join(BOPOMOFO_TABLE.get(x, x) for x in pinyin)
|
||||
return pinyin
|
||||
|
||||
def to_bopomofo_first(self, pinyin, **kwargs):
|
||||
pinyin = self.to_bopomofo(pinyin, **kwargs)
|
||||
return pinyin[0]
|
||||
|
||||
def _pre_convert(self, pinyin):
|
||||
# 用数字表示声调
|
||||
pinyin = replace_symbol_to_number(pinyin)
|
||||
# 将声调数字移动到最后
|
||||
return RE_TONE3.sub(r'\1\3\2', pinyin)
|
||||
|
||||
|
||||
converter = BopomofoConverter()
|
||||
register(Style.BOPOMOFO, func=converter.to_bopomofo)
|
||||
register(Style.BOPOMOFO_FIRST, func=converter.to_bopomofo_first)
|
||||
@@ -0,0 +1,15 @@
|
||||
from typing import Any, Dict, Tuple, Text
|
||||
|
||||
# 注音转换表
|
||||
BOPOMOFO_REPLACE = ... # type: Tuple[Tuple[Any]]
|
||||
BOPOMOFO_TABLE = ... # type: Dict[Text, Text]
|
||||
|
||||
|
||||
class BopomofoConverter(object):
|
||||
def to_bopomofo(self, pinyin: Text, **kwargs: Any) -> Text: ...
|
||||
|
||||
def to_bopomofo_first(self, pinyin: Text, **kwargs: Any) -> Text: ...
|
||||
|
||||
def _pre_convert(self, pinyin: Text) -> Text: ...
|
||||
|
||||
converter = ... # type: BopomofoConverter
|
||||
@@ -0,0 +1,93 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""中国内地盲文相关的几个拼音风格实现:
|
||||
|
||||
Style.BRAILLE_MAINLAND
|
||||
Style.BRAILLE_MAINLAND_TONE
|
||||
|
||||
https://en.wikipedia.org/wiki/Mainland_Chinese_Braille
|
||||
"""
|
||||
from __future__ import unicode_literals
|
||||
import re
|
||||
|
||||
from pypinyin.constants import Style
|
||||
from pypinyin.style import register
|
||||
from pypinyin.style._constants import RE_TONE3
|
||||
from pypinyin.style._utils import (
|
||||
replace_symbol_to_number, replace_symbol_to_no_symbol)
|
||||
|
||||
BRAILLE_MAINLAND_REPLACE = (
|
||||
(re.compile(r'iu'), 'iou'),
|
||||
(re.compile(r'ui'), 'uei'),
|
||||
(re.compile(r'un'), 'uen'),
|
||||
(re.compile(r'ong'), 'ung'),
|
||||
(re.compile(r'^yi?'), 'i'),
|
||||
(re.compile(r'^wu?'), 'u'),
|
||||
(re.compile(r'y'), 'i'),
|
||||
(re.compile(r'w'), 'u'),
|
||||
(re.compile(r'iu'), 'v'),
|
||||
(re.compile(r'^([jqx])u'), '\\1v'),
|
||||
(re.compile(r'([iuv])n'), '\\1en'),
|
||||
(re.compile(r'^zhi?'), 'Z'),
|
||||
(re.compile(r'^chi?'), 'C'),
|
||||
(re.compile(r'^shi?'), 'S'),
|
||||
(re.compile(r'^([zcsr])i'), '\\1'),
|
||||
(re.compile(r'iang'), '⠭'),
|
||||
(re.compile(r'uang'), '⠶'),
|
||||
(re.compile(r'ueng'), '⠲'),
|
||||
(re.compile(r'iong'), '⠹'),
|
||||
(re.compile(r'ang'), '⠦'),
|
||||
(re.compile(r'eng'), '⠼'),
|
||||
(re.compile(r'uai'), '⠽'),
|
||||
(re.compile(r'iao'), '⠜'),
|
||||
(re.compile(r'iou'), '⠳'),
|
||||
(re.compile(r'ian'), '⠩'),
|
||||
(re.compile(r'uan'), '⠻'),
|
||||
(re.compile(r'van'), '⠯'),
|
||||
(re.compile(r'uen'), '⠒'),
|
||||
(re.compile(r'ing'), '⠡'),
|
||||
(re.compile(r'ong'), '⠲'),
|
||||
(re.compile(r'er'), '⠗'),
|
||||
(re.compile(r'ai'), '⠪'),
|
||||
(re.compile(r'ei'), '⠮'),
|
||||
(re.compile(r'ao'), '⠖'),
|
||||
(re.compile(r'ou'), '⠷'),
|
||||
(re.compile(r'an'), '⠧'),
|
||||
(re.compile(r'en'), '⠴'),
|
||||
(re.compile(r'ia'), '⠫'),
|
||||
(re.compile(r'ua'), '⠿'),
|
||||
(re.compile(r'ie'), '⠑'),
|
||||
(re.compile(r'uo'), '⠕'),
|
||||
(re.compile(r've'), '⠾'),
|
||||
(re.compile(r'ui'), '⠺'),
|
||||
(re.compile(r'in'), '⠣'),
|
||||
(re.compile(r'vn'), '⠸'),
|
||||
)
|
||||
|
||||
BRAILLE_MAINLAND_TABLE = dict(zip(
|
||||
'bpmfdtnlgkhjqxZCSrzcsiuvaoe1234',
|
||||
'⠃⠏⠍⠋⠙⠞⠝⠇⠛⠅⠓⠛⠅⠓⠌⠟⠱⠚⠵⠉⠎⠊⠥⠬⠔⠢⠢⠁⠂⠄⠆'
|
||||
))
|
||||
|
||||
|
||||
class BrailleMainlandConverter(object):
|
||||
def to_braille_mainland_tone(self, pinyin, **kwargs):
|
||||
# 用数字表示声调
|
||||
pinyin = replace_symbol_to_number(pinyin)
|
||||
# 将声调数字移动到最后
|
||||
pinyin = RE_TONE3.sub(r'\1\3\2', pinyin)
|
||||
for find_re, replace in BRAILLE_MAINLAND_REPLACE:
|
||||
pinyin = find_re.sub(replace, pinyin)
|
||||
pinyin = ''.join(BRAILLE_MAINLAND_TABLE.get(x, x) for x in pinyin)
|
||||
return pinyin
|
||||
|
||||
def to_braille_mainland(self, pinyin, **kwargs):
|
||||
pinyin = replace_symbol_to_no_symbol(pinyin)
|
||||
for find_re, replace in BRAILLE_MAINLAND_REPLACE:
|
||||
pinyin = find_re.sub(replace, pinyin)
|
||||
pinyin = ''.join(BRAILLE_MAINLAND_TABLE.get(x, x) for x in pinyin)
|
||||
return pinyin
|
||||
|
||||
|
||||
converter = BrailleMainlandConverter()
|
||||
register(Style.BRAILLE_MAINLAND_TONE, func=converter.to_braille_mainland_tone)
|
||||
register(Style.BRAILLE_MAINLAND, func=converter.to_braille_mainland)
|
||||
@@ -0,0 +1,18 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""中国内地盲文相关的几个拼音风格实现:
|
||||
|
||||
Style.BRAILLE_MAINLAND
|
||||
Style.BRAILLE_MAINLAND_TONE
|
||||
"""
|
||||
from typing import Any, Dict, Tuple, Text
|
||||
|
||||
BRAILLE_MAINLAND_REPLACE = ... # type: Tuple[Tuple[Any]]
|
||||
|
||||
BRAILLE_MAINLAND_TABLE = ... # type: Dict[Text, Text]
|
||||
|
||||
class BrailleMainlandConverter(object):
|
||||
def to_braille_mainland_tone(self, pinyin: Text, **kwargs: Any) -> Text: ...
|
||||
|
||||
def to_braille_mainland(self, pinyin: Text, **kwargs: Any) -> Text: ...
|
||||
|
||||
converter = ... # type: BrailleMainlandConverter
|
||||
@@ -0,0 +1,77 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""CYRILLIC 相关的几个拼音风格实现:
|
||||
|
||||
Style.CYRILLIC
|
||||
Style.CYRILLIC_FIRST
|
||||
"""
|
||||
from __future__ import unicode_literals
|
||||
import re
|
||||
|
||||
from pypinyin.constants import Style
|
||||
from pypinyin.style import register
|
||||
from pypinyin.style._constants import RE_TONE3
|
||||
from pypinyin.style._utils import replace_symbol_to_number
|
||||
|
||||
# 俄语转换表
|
||||
CYRILLIC_REPLACE = (
|
||||
(re.compile(r'ong'), 'ung'),
|
||||
(re.compile(r'([zcs])i'), '\\1U'),
|
||||
(re.compile(r'([xqj])u'), '\\1v'),
|
||||
(re.compile(r'^wu(.?)$'), 'u\\1'),
|
||||
(re.compile(r'(.+)r(.?)$'), '\\1R\\2'),
|
||||
(re.compile(r'^zh'), 'Cr'),
|
||||
(re.compile(r'^ch'), 'C'),
|
||||
(re.compile(r'^j'), 'qZ'),
|
||||
(re.compile(r'^z'), 'qZ'),
|
||||
(re.compile(r'^x'), 's'),
|
||||
(re.compile(r'^sh'), 'S'),
|
||||
(re.compile(r'([^CSdst])uo'), '\\1o'),
|
||||
(re.compile(r'^y(.*)$'), 'I\\1'),
|
||||
(re.compile(r'Iai'), 'AI'),
|
||||
(re.compile(r'Ia'), 'A'),
|
||||
(re.compile(r'Ie'), 'E'),
|
||||
(re.compile(r'Ii'), 'i'),
|
||||
(re.compile(r'Iou'), 'V'),
|
||||
(re.compile(r'Iu'), 'v'),
|
||||
(re.compile(r'(.v)(\d?)$'), '\\1I\\2'),
|
||||
(re.compile(r'Io'), 'O'),
|
||||
(re.compile(r'iu'), 'v'),
|
||||
(re.compile(r'ie'), 'E'),
|
||||
(re.compile(r'hui'), 'huei'),
|
||||
(re.compile(r'ui'), 'uI'),
|
||||
(re.compile(r'ai'), 'aI'),
|
||||
(re.compile(r'ei'), 'eI'),
|
||||
(re.compile(r'ia'), 'A'),
|
||||
(re.compile(r'(.*[^h])n([^g]?)$'), '\\1nM\\2'),
|
||||
(re.compile(r'(.*[^h])ng(.?)$'), '\\1n\\2'),
|
||||
(re.compile(r'^v(\d?$)'), 'vI'),
|
||||
)
|
||||
CYRILLIC_TABLE = dict(zip(
|
||||
u'abwgdEOrZiIklmnopRstufhqcCSHTMUevAV',
|
||||
u'абвгдеёжзийклмнопрстуфхццчшщъьыэюяю'
|
||||
))
|
||||
|
||||
|
||||
class CyrillicfoConverter(object):
|
||||
def to_cyrillic(self, pinyin, **kwargs):
|
||||
pinyin = self._pre_convert(pinyin)
|
||||
# 查表替换成注音
|
||||
for find_re, replace in CYRILLIC_REPLACE:
|
||||
pinyin = find_re.sub(replace, pinyin)
|
||||
pinyin = ''.join(CYRILLIC_TABLE.get(x, x) for x in pinyin)
|
||||
return pinyin
|
||||
|
||||
def to_cyrillic_first(self, pinyin, **kwargs):
|
||||
pinyin = self.to_cyrillic(pinyin, **kwargs)
|
||||
return pinyin[0]
|
||||
|
||||
def _pre_convert(self, pinyin):
|
||||
# 用数字表示声调
|
||||
pinyin = replace_symbol_to_number(pinyin)
|
||||
# 将声调数字移动到最后
|
||||
return RE_TONE3.sub(r'\1\3\2', pinyin)
|
||||
|
||||
|
||||
converter = CyrillicfoConverter()
|
||||
register(Style.CYRILLIC, func=converter.to_cyrillic)
|
||||
register(Style.CYRILLIC_FIRST, func=converter.to_cyrillic_first)
|
||||
@@ -0,0 +1,16 @@
|
||||
from typing import Any, Dict, Tuple, Text
|
||||
|
||||
# 俄语转换表
|
||||
CYRILLIC_REPLACE = ... # type: Tuple[Tuple[Any]]
|
||||
CYRILLIC_TABLE = ... # type: Dict[Text, Text]
|
||||
|
||||
|
||||
class CyrillicfoConverter(object):
|
||||
def to_cyrillic(self, pinyin: Text, **kwargs: Any) -> Text: ...
|
||||
|
||||
def to_cyrillic_first(self, pinyin: Text, **kwargs: Any) -> Text: ...
|
||||
|
||||
def _pre_convert(self, pinyin: Text) -> Text: ...
|
||||
|
||||
|
||||
converter = ... # type: CyrillicfoConverter
|
||||
@@ -0,0 +1,40 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""韵母相关拼音风格:
|
||||
|
||||
Style.FINALS
|
||||
Style.FINALS_TONE
|
||||
Style.FINALS_TONE2
|
||||
Style.FINALS_TONE3
|
||||
"""
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from pypinyin.constants import Style
|
||||
from pypinyin.style import register
|
||||
from pypinyin.style._tone_convert import (
|
||||
to_finals, to_finals_tone, to_finals_tone2, to_finals_tone3
|
||||
)
|
||||
|
||||
|
||||
class FinalsConverter(object):
|
||||
def to_finals(self, pinyin, **kwargs):
|
||||
"""无声调韵母"""
|
||||
return to_finals(pinyin, strict=kwargs.get('strict', True))
|
||||
|
||||
def to_finals_tone(self, pinyin, **kwargs):
|
||||
"""声调在韵母头上"""
|
||||
return to_finals_tone(pinyin, strict=kwargs.get('strict', True))
|
||||
|
||||
def to_finals_tone2(self, pinyin, **kwargs):
|
||||
"""数字声调"""
|
||||
return to_finals_tone2(pinyin, strict=kwargs.get('strict', True))
|
||||
|
||||
def to_finals_tone3(self, pinyin, **kwargs):
|
||||
"""数字声调"""
|
||||
return to_finals_tone3(pinyin, strict=kwargs.get('strict', True))
|
||||
|
||||
|
||||
converter = FinalsConverter()
|
||||
register(Style.FINALS, func=converter.to_finals)
|
||||
register(Style.FINALS_TONE, func=converter.to_finals_tone)
|
||||
register(Style.FINALS_TONE2, func=converter.to_finals_tone2)
|
||||
register(Style.FINALS_TONE3, func=converter.to_finals_tone3)
|
||||
@@ -0,0 +1,14 @@
|
||||
from typing import Any, Text
|
||||
|
||||
|
||||
class FinalsConverter(object):
|
||||
def to_finals(self, pinyin: Text, **kwargs: Any) -> Text: ...
|
||||
|
||||
def to_finals_tone(self, pinyin: Text, **kwargs: Any) -> Text: ...
|
||||
|
||||
def to_finals_tone2(self, pinyin: Text, **kwargs: Any) -> Text: ...
|
||||
|
||||
def to_finals_tone3(self, pinyin: Text, **kwargs: Any) -> Text: ...
|
||||
|
||||
|
||||
converter = ... # type: FinalsConverter
|
||||
@@ -0,0 +1,77 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
import re
|
||||
|
||||
from pypinyin.constants import Style
|
||||
from pypinyin.style import register
|
||||
from pypinyin.style._constants import RE_TONE3
|
||||
from pypinyin.style._utils import replace_symbol_to_number
|
||||
|
||||
GWOYEU_REPLACE = (
|
||||
(re.compile(r'^r5$'), 'er5'),
|
||||
(re.compile(r'iu'), 'iou'),
|
||||
(re.compile(r'ao'), 'au'),
|
||||
(re.compile(r'^yi?'), 'i'),
|
||||
(re.compile(r'^wu?'), 'u'),
|
||||
(re.compile(r'^([jqx])u'), '\\1iu'),
|
||||
(re.compile(r'(?<![iy])u([in])'), 'ue\\1'),
|
||||
(re.compile(r'v'), 'iu'),
|
||||
(re.compile(r'^([zcsr]h?)i'), '\\1y'),
|
||||
(re.compile(r'^zh'), 'j'),
|
||||
(re.compile(r'^z'), 'tz'),
|
||||
(re.compile(r'^c(?!h)'), 'ts'),
|
||||
(re.compile(r'^q'), 'ch'),
|
||||
(re.compile(r'^x'), 'sh'),
|
||||
(re.compile(r'er'), 'el'),
|
||||
(re.compile(r'5$'), ''),
|
||||
(re.compile(r'0$'), 'q'),
|
||||
(re.compile(r'^i(.*[34])$'), 'yi\\1'),
|
||||
(re.compile(r'^u(.*[34])$'), 'wu\\1'),
|
||||
(re.compile(r'^yi([aeu].*4)$'), 'y\\1'),
|
||||
(re.compile(r'^wu([ae].*4)$'), 'w\\1'),
|
||||
)
|
||||
|
||||
TONE_REPLACE = (
|
||||
(re.compile(r'^([lmnr])(.+)1$'), '\\1h\\2'),
|
||||
(re.compile(r'1$'), ''),
|
||||
(re.compile(r'^([lmnr])(.+)2$'), '\\1\\2'),
|
||||
(re.compile(r'^([^ae]*)i(ng?)*2$'), '\\1yi\\2'),
|
||||
(re.compile(r'^([^ao]*)u2$'), '\\1wu'),
|
||||
(re.compile(r'^([^ae]*)i(.+)2$'), '\\1y\\2'),
|
||||
(re.compile(r'^([^ao]*)u(.+)2$'), '\\1w\\2'),
|
||||
(re.compile(r'([aeiouy]+)(.*)2$'), '\\1r\\2'),
|
||||
(re.compile(r'^([^aeiou]*)([iu])(ng?)?3$'), '\\1\\2\\2\\3'),
|
||||
(re.compile(r'^([^eu]*)i(.*)3$'), '\\1e\\2'),
|
||||
(re.compile(r'^(.*)u(.*)3$'), '\\1o\\2'),
|
||||
(re.compile(r'([aeiouy])(.*)3$'), '\\1\\1\\2'),
|
||||
(re.compile(r'^([^ae]*)i4$'), '\\1ih'),
|
||||
(re.compile(r'^([^ao]*)u4$'), '\\1uh'),
|
||||
(re.compile(r'i4$'), 'y'),
|
||||
(re.compile(r'u4$'), 'w'),
|
||||
(re.compile(r'l4$'), 'll'),
|
||||
(re.compile(r'ng4$'), 'nq'),
|
||||
(re.compile(r'n4$'), 'nn'),
|
||||
(re.compile(r'4$'), 'h'),
|
||||
)
|
||||
|
||||
|
||||
class GwoyeuConverter(object):
|
||||
def _pre_convert(self, pinyin):
|
||||
# 用数字表示声调
|
||||
pinyin = replace_symbol_to_number(pinyin)
|
||||
# 将声调数字移动到最后
|
||||
return RE_TONE3.sub(r'\1\3\2', pinyin)
|
||||
|
||||
def to_gwoyeu(self, pinyin, **kwargs):
|
||||
pinyin = self._pre_convert(pinyin)
|
||||
for find_re, replace in GWOYEU_REPLACE:
|
||||
pinyin = find_re.sub(replace, pinyin)
|
||||
for find_re, replace in TONE_REPLACE:
|
||||
if find_re.search(pinyin):
|
||||
return find_re.sub(replace, pinyin)
|
||||
return pinyin
|
||||
|
||||
|
||||
converter = GwoyeuConverter()
|
||||
|
||||
register(Style.GWOYEU, func=converter.to_gwoyeu)
|
||||
@@ -0,0 +1,10 @@
|
||||
from typing import Any, Text, Tuple
|
||||
|
||||
GWOYEU_REPLACE = ... # type: Tuple[Tuple[Any]]
|
||||
|
||||
class GwoyeuConverter(object):
|
||||
def to_wade_glides(self, pinyin: Text, **kwargs: Any) -> Text: ...
|
||||
|
||||
def _pre_convert(self, pinyin: Text) -> Text: ...
|
||||
|
||||
converter = ... # type: GwoyeuConverter
|
||||
@@ -0,0 +1,13 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Style.INITIALS 风格"""
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from pypinyin.constants import Style
|
||||
from pypinyin.style import register
|
||||
from pypinyin.style._utils import get_initials
|
||||
|
||||
|
||||
@register(Style.INITIALS)
|
||||
def convert(pinyin, **kwargs):
|
||||
strict = kwargs.get('strict', True)
|
||||
return get_initials(pinyin, strict)
|
||||
@@ -0,0 +1,4 @@
|
||||
from typing import Any, Text
|
||||
|
||||
|
||||
def convert(pinyin: Text, **kwargs: Any) -> Text: ...
|
||||
@@ -0,0 +1,27 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""其他几个拼音风格实现:
|
||||
|
||||
Style.NORMAL
|
||||
Style.FIRST_LETTER
|
||||
"""
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from pypinyin.constants import Style
|
||||
from pypinyin.style import register
|
||||
from pypinyin.style._utils import replace_symbol_to_no_symbol
|
||||
|
||||
|
||||
class OthersConverter(object):
|
||||
def to_normal(self, pinyin, **kwargs):
|
||||
pinyin = replace_symbol_to_no_symbol(pinyin)
|
||||
return pinyin
|
||||
|
||||
def to_first_letter(self, pinyin, **kwargs):
|
||||
# 用数字表示声调
|
||||
pinyin = self.to_normal(pinyin)
|
||||
return pinyin[0]
|
||||
|
||||
|
||||
converter = OthersConverter()
|
||||
register(Style.NORMAL, func=converter.to_normal)
|
||||
register(Style.FIRST_LETTER, func=converter.to_first_letter)
|
||||
@@ -0,0 +1,10 @@
|
||||
from typing import Any, Text
|
||||
|
||||
|
||||
class OthersConverter(object):
|
||||
def to_normal(self, pinyin: Text, **kwargs: Any) -> Text: ...
|
||||
|
||||
def to_first_letter(self, pinyin: Text, **kwargs: Any) -> Text: ...
|
||||
|
||||
|
||||
converter = ... # type: OthersConverter
|
||||
@@ -0,0 +1,34 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""TONE 相关的几个拼音风格实现:
|
||||
|
||||
Style.TONE
|
||||
Style.TONE2
|
||||
Style.TONE3
|
||||
"""
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from pypinyin.constants import Style
|
||||
from pypinyin.style import register
|
||||
from pypinyin.style._constants import RE_TONE3
|
||||
from pypinyin.style._utils import replace_symbol_to_number
|
||||
|
||||
|
||||
class ToneConverter(object):
|
||||
def to_tone(self, pinyin, **kwargs):
|
||||
return pinyin
|
||||
|
||||
def to_tone2(self, pinyin, **kwargs):
|
||||
# 用数字表示声调
|
||||
pinyin = replace_symbol_to_number(pinyin)
|
||||
return pinyin
|
||||
|
||||
def to_tone3(self, pinyin, **kwargs):
|
||||
pinyin = self.to_tone2(pinyin, **kwargs)
|
||||
# 将声调数字移动到最后
|
||||
return RE_TONE3.sub(r'\1\3\2', pinyin)
|
||||
|
||||
|
||||
converter = ToneConverter()
|
||||
register(Style.TONE, func=converter.to_tone)
|
||||
register(Style.TONE2, func=converter.to_tone2)
|
||||
register(Style.TONE3, func=converter.to_tone3)
|
||||
@@ -0,0 +1,12 @@
|
||||
from typing import Any, Text
|
||||
|
||||
|
||||
class ToneConverter(object):
|
||||
def to_tone(self, pinyin: Text, **kwargs: Any) -> Text: ...
|
||||
|
||||
def to_tone2(self, pinyin: Text, **kwargs: Any) -> Text: ...
|
||||
|
||||
def to_tone3(self, pinyin: Text, **kwargs: Any) -> Text: ...
|
||||
|
||||
|
||||
converter = ... # type: ToneConverter
|
||||
@@ -0,0 +1,559 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from pypinyin.constants import Style
|
||||
from pypinyin.style import register
|
||||
from pypinyin.style._utils import replace_symbol_to_no_symbol
|
||||
from pypinyin.style._utils import get_initials
|
||||
|
||||
# https://en.wikipedia.org/wiki/Wade%E2%80%93Giles
|
||||
# https://web.archive.org/web/20070128065433/http://polaris.gseis.ucla.edu/skozerow/wadegiles.htm
|
||||
# https://www.lib.uchicago.edu/about/directory/departments/eastasia/find/wade-giles-pinyin-conversion-table/
|
||||
# https://www.zdic.net/ts/fulu/2019/05/18.html
|
||||
_convert_table = [
|
||||
|
||||
['a', 'a'],
|
||||
['ai', 'ai'],
|
||||
['an', 'an'],
|
||||
['ang', 'ang'],
|
||||
['ao', 'ao'],
|
||||
['zha', 'cha'],
|
||||
['cha', 'ch\'a'],
|
||||
['zhai', 'chai'],
|
||||
['chai', 'ch\'ai'],
|
||||
['zhan', 'chan'],
|
||||
['chan', 'ch\'an'],
|
||||
['zhang', 'chang'],
|
||||
['chang', 'ch\'ang'],
|
||||
['zhao', 'chao'],
|
||||
['chao', 'ch\'ao'],
|
||||
['zhe', 'che'],
|
||||
['che', 'ch\'e'],
|
||||
['zhen', 'chen'],
|
||||
['chen', 'ch\'en'],
|
||||
['zheng', 'cheng'],
|
||||
['cheng', 'ch\'eng'],
|
||||
['ji', 'chi'],
|
||||
['qi', 'ch\'i'],
|
||||
['jia', 'chia'],
|
||||
['qia', 'ch\'ia'],
|
||||
['jiang', 'chiang'],
|
||||
['qiang', 'ch\'iang'],
|
||||
['jiao', 'chiao'],
|
||||
['qiao', 'ch\'iao'],
|
||||
['jie', 'chieh'],
|
||||
['qie', 'ch\'ieh'],
|
||||
['jian', 'chien'],
|
||||
['qian', 'ch\'ien'],
|
||||
['zhi', 'chih'],
|
||||
['chi', 'ch\'ih'],
|
||||
['jin', 'chin'],
|
||||
['qin', 'ch\'in'],
|
||||
['jing', 'ching'],
|
||||
['qing', 'ch\'ing'],
|
||||
['jiu', 'chiu'],
|
||||
['qiu', 'ch\'iu'],
|
||||
['jiong', 'chiung'],
|
||||
['qiong', 'ch\'iung'],
|
||||
['zhuo', 'cho'],
|
||||
['chuo', 'ch\'o'],
|
||||
['zhou', 'chou'],
|
||||
['chou', 'ch\'ou'],
|
||||
['zhu', 'chu'],
|
||||
['chu', 'ch\'u'],
|
||||
['ju', 'chü'],
|
||||
['qu', 'ch\'ü'],
|
||||
['zhua', 'chua'],
|
||||
['zhuai', 'chuai'],
|
||||
['chuai', 'ch\'uai'],
|
||||
['zhuan', 'chuan'],
|
||||
['chuan', 'ch\'uan'],
|
||||
['juan', 'chüan'],
|
||||
['quan', 'ch\'üan'],
|
||||
['zhuang', 'chuang'],
|
||||
['chuang', 'ch\'uang'],
|
||||
['jue', 'chüeh'],
|
||||
['que', 'ch\'üeh'],
|
||||
['zhui', 'chui'],
|
||||
['chui', 'ch\'ui'],
|
||||
['zhun', 'chun'],
|
||||
['chun', 'ch\'un'],
|
||||
['jun', 'chün'],
|
||||
['qun', 'ch\'ün'],
|
||||
['zhong', 'chung'],
|
||||
['chong', 'ch\'ung'],
|
||||
['en', 'en'],
|
||||
['er', 'erh'],
|
||||
['fa', 'fa'],
|
||||
['fan', 'fan'],
|
||||
['fang', 'fang'],
|
||||
['fei', 'fei'],
|
||||
['fen', 'fen'],
|
||||
['feng', 'feng'],
|
||||
['fo', 'fo'],
|
||||
['fou', 'fou'],
|
||||
['fu', 'fu'],
|
||||
['ha', 'ha'],
|
||||
['hai', 'hai'],
|
||||
['han', 'han'],
|
||||
['hang', 'hang'],
|
||||
['hao', 'hao'],
|
||||
['hei', 'hei'],
|
||||
['hen', 'hen'],
|
||||
['heng', 'heng'],
|
||||
['he', 'ho'],
|
||||
['hou', 'hou'],
|
||||
['xi', 'hsi'],
|
||||
['xia', 'hsia'],
|
||||
['xiang', 'hsiang'],
|
||||
['xiao', 'hsiao'],
|
||||
['xie', 'hsieh'],
|
||||
['xian', 'hsien'],
|
||||
['xin', 'hsin'],
|
||||
['xing', 'hsing'],
|
||||
['xiu', 'hsiu'],
|
||||
['xiong', 'hsiung'],
|
||||
['xu', 'hsü'],
|
||||
['xuan', 'hsüan'],
|
||||
['xue', 'hsüeh'],
|
||||
['xun', 'hsün'],
|
||||
['hu', 'hu'],
|
||||
['hua', 'hua'],
|
||||
['huai', 'huai'],
|
||||
['huan', 'huan'],
|
||||
['huang', 'huang'],
|
||||
['hui', 'hui'],
|
||||
['hun', 'hun'],
|
||||
['hong', 'hung'],
|
||||
['huo', 'huo'],
|
||||
['yi', 'i'],
|
||||
['ran', 'jan'],
|
||||
['rang', 'jang'],
|
||||
['rao', 'jao'],
|
||||
['re', 'je'],
|
||||
['ren', 'jen'],
|
||||
['reng', 'jeng'],
|
||||
['ri', 'jih'],
|
||||
['ruo', 'jo'],
|
||||
['rou', 'jou'],
|
||||
['ru', 'ju'],
|
||||
['ruan', 'juan'],
|
||||
['rui', 'jui'],
|
||||
['run', 'jun'],
|
||||
['rong', 'jung'],
|
||||
['ga', 'ka'],
|
||||
['ka', 'k\'a'],
|
||||
['gai', 'kai'],
|
||||
['kai', 'k\'ai'],
|
||||
['gan', 'kan'],
|
||||
['kan', 'k\'an'],
|
||||
['gang', 'kang'],
|
||||
['kang', 'k\'ang'],
|
||||
['gao', 'kao'],
|
||||
['kao', 'k\'ao'],
|
||||
['gen', 'ken'],
|
||||
['ken', 'k\'en'],
|
||||
['geng', 'keng'],
|
||||
['keng', 'k\'eng'],
|
||||
['ge', 'ko'],
|
||||
['ke', 'k\'o'],
|
||||
['gou', 'kou'],
|
||||
['kou', 'k\'ou'],
|
||||
['gu', 'ku'],
|
||||
['ku', 'k\'u'],
|
||||
['gua', 'kua'],
|
||||
['kua', 'k\'ua'],
|
||||
['guai', 'kuai'],
|
||||
['kuai', 'k\'uai'],
|
||||
['guan', 'kuan'],
|
||||
['kuan', 'k\'uan'],
|
||||
['guang', 'kuang'],
|
||||
['kuang', 'k\'uang'],
|
||||
['gui', 'kuei'],
|
||||
['kui', 'k\'uei'],
|
||||
['gun', 'kun'],
|
||||
['kun', 'k\'un'],
|
||||
['gong', 'kung'],
|
||||
['kong', 'k\'ung'],
|
||||
['guo', 'kuo'],
|
||||
['kuo', 'k\'uo'],
|
||||
['la', 'la'],
|
||||
['lai', 'lai'],
|
||||
['lan', 'lan'],
|
||||
['lang', 'lang'],
|
||||
['lao', 'lao'],
|
||||
['le', 'le'],
|
||||
['lei', 'lei'],
|
||||
['leng', 'leng'],
|
||||
['li', 'li'],
|
||||
['liang', 'liang'],
|
||||
['liao', 'liao'],
|
||||
['lie', 'lieh'],
|
||||
['lian', 'lien'],
|
||||
['lin', 'lin'],
|
||||
['ling', 'ling'],
|
||||
['liu', 'liu'],
|
||||
['luo', 'lo'],
|
||||
['lou', 'lou'],
|
||||
['lu', 'lu'],
|
||||
['lü', 'lü'],
|
||||
['luan', 'luan'],
|
||||
['luan', 'lüan'],
|
||||
['lue', 'lüeh'],
|
||||
['lun', 'lun'],
|
||||
['long', 'lung'],
|
||||
['ma', 'ma'],
|
||||
['mai', 'mai'],
|
||||
['man', 'man'],
|
||||
['mang', 'mang'],
|
||||
['mao', 'mao'],
|
||||
['mei', 'mei'],
|
||||
['men', 'men'],
|
||||
['meng', 'meng'],
|
||||
['mi', 'mi'],
|
||||
['miao', 'miao'],
|
||||
['mie', 'mieh'],
|
||||
['mian', 'mien'],
|
||||
['min', 'min'],
|
||||
['ming', 'ming'],
|
||||
['miu', 'miu'],
|
||||
['mo', 'mo'],
|
||||
['mou', 'mou'],
|
||||
['mu', 'mu'],
|
||||
['na', 'na'],
|
||||
['nai', 'nai'],
|
||||
['nan', 'nan'],
|
||||
['nang', 'nang'],
|
||||
['nao', 'nao'],
|
||||
['nei', 'nei'],
|
||||
['nen', 'nen'],
|
||||
['neng', 'neng'],
|
||||
['ni', 'ni'],
|
||||
['niang', 'niang'],
|
||||
['niao', 'niao'],
|
||||
['nie', 'nieh'],
|
||||
['nian', 'nien'],
|
||||
['nin', 'nin'],
|
||||
['ning', 'ning'],
|
||||
['niu', 'niu'],
|
||||
['nuo', 'no'],
|
||||
['nou', 'nou'],
|
||||
['nu', 'nu'],
|
||||
['nü', 'nü'],
|
||||
['nuan', 'nuan'],
|
||||
['nue', 'nüeh'],
|
||||
['nong', 'nung'],
|
||||
['e', 'o'],
|
||||
['ou', 'ou'],
|
||||
['ba', 'pa'],
|
||||
['pa', 'p\'a'],
|
||||
['bai', 'pai'],
|
||||
['pai', 'p\'ai'],
|
||||
['ban', 'pan'],
|
||||
['pan', 'p\'an'],
|
||||
['bang', 'pang'],
|
||||
['pang', 'p\'ang'],
|
||||
['bao', 'pao'],
|
||||
['pao', 'p\'ao'],
|
||||
['bei', 'pei'],
|
||||
['pei', 'p\'ei'],
|
||||
['ben', 'pen'],
|
||||
['pen', 'p\'en'],
|
||||
['beng', 'peng'],
|
||||
['peng', 'p\'eng'],
|
||||
['bi', 'pi'],
|
||||
['pi', 'p\'i'],
|
||||
['biao', 'piao'],
|
||||
['piao', 'p\'iao'],
|
||||
['bie', 'pieh'],
|
||||
['pie', 'p\'ieh'],
|
||||
['bian', 'pien'],
|
||||
['pian', 'p\'ien'],
|
||||
['bin', 'pin'],
|
||||
['pin', 'p\'in'],
|
||||
['bing', 'ping'],
|
||||
['ping', 'p\'ing'],
|
||||
['bo', 'po'],
|
||||
['po', 'p\'o'],
|
||||
['pou', 'p\'ou'],
|
||||
['bu', 'pu'],
|
||||
['pu', 'p\'u'],
|
||||
['sa', 'sa'],
|
||||
['sai', 'sai'],
|
||||
['san', 'san'],
|
||||
['sang', 'sang'],
|
||||
['sao', 'sao'],
|
||||
['se', 'se'],
|
||||
['sen', 'sen'],
|
||||
['seng', 'seng'],
|
||||
['sha', 'sha'],
|
||||
['shai', 'shai'],
|
||||
['shan', 'shan'],
|
||||
['shang', 'shang'],
|
||||
['shao', 'shao'],
|
||||
['she', 'she'],
|
||||
['shen', 'shen'],
|
||||
['sheng', 'sheng'],
|
||||
['shi', 'shih'],
|
||||
['shou', 'shou'],
|
||||
['shu', 'shu'],
|
||||
['shua', 'shua'],
|
||||
['shuai', 'shuai'],
|
||||
['shuan', 'shuan'],
|
||||
['shuang', 'shuang'],
|
||||
['shui', 'shui'],
|
||||
['shun', 'shun'],
|
||||
['shuo', 'shuo'],
|
||||
['suo', 'so'],
|
||||
['sou', 'sou'],
|
||||
['si', 'ssu'],
|
||||
['su', 'su'],
|
||||
['suan', 'suan'],
|
||||
['sui', 'sui'],
|
||||
['sun', 'sun'],
|
||||
['song', 'sung'],
|
||||
['da', 'ta'],
|
||||
['ta', 't\'a'],
|
||||
['dai', 'tai'],
|
||||
['tai', 't\'ai'],
|
||||
['dan', 'tan'],
|
||||
['tan', 't\'an'],
|
||||
['dang', 'tang'],
|
||||
['tang', 't\'ang'],
|
||||
['dao', 'tao'],
|
||||
['tao', 't\'ao'],
|
||||
['de', 'te'],
|
||||
['te', 't\'e'],
|
||||
['deng', 'teng'],
|
||||
['teng', 't\'eng'],
|
||||
['di', 'ti'],
|
||||
['ti', 't\'i'],
|
||||
['diao', 'tiao'],
|
||||
['tiao', 't\'iao'],
|
||||
['die', 'tieh'],
|
||||
['tie', 't\'oeh'],
|
||||
['dian', 'tien'],
|
||||
['tian', 't\'ien'],
|
||||
['ding', 'ting'],
|
||||
['ting', 't\'ing'],
|
||||
['diu', 'tiu'],
|
||||
['duo', 'to'],
|
||||
['tuo', 't\'o'],
|
||||
['dou', 'tou'],
|
||||
['tou', 't\'ou'],
|
||||
['du', 'tu'],
|
||||
['tu', 't\'u'],
|
||||
['duan', 'tuan'],
|
||||
['tuan', 't\'uan'],
|
||||
['dui', 'tui'],
|
||||
['tui', 't\'ui'],
|
||||
['dun', 'tun'],
|
||||
['tun', 't\'un'],
|
||||
['dong', 'tung'],
|
||||
['tong', 't\'ung'],
|
||||
['za', 'tsa'],
|
||||
['ca', 'ts\'a'],
|
||||
['zai', 'tsai'],
|
||||
['cai', 'ts\'ai'],
|
||||
['zan', 'tsan'],
|
||||
['can', 'ts\'an'],
|
||||
['zang', 'tsang'],
|
||||
['cang', 'ts\'ang'],
|
||||
['zao', 'tsao'],
|
||||
['cao', 'ts\'ao'],
|
||||
['ze', 'tse'],
|
||||
['ce', 'ts\'e'],
|
||||
['zei', 'tsei'],
|
||||
['zen', 'tsen'],
|
||||
['cen', 'ts\'en'],
|
||||
['zeng', 'tseng'],
|
||||
['ceng', 'ts\'eng'],
|
||||
['zuo', 'tso'],
|
||||
['cuo', 'ts\'o'],
|
||||
['zou', 'tsou'],
|
||||
['cou', 'ts\'ou'],
|
||||
['zu', 'tsu'],
|
||||
['cu', 'ts\'u'],
|
||||
['zuan', 'tsuan'],
|
||||
['cuan', 'ts\'uan'],
|
||||
['zui', 'tsui'],
|
||||
['cui', 'ts\'ui'],
|
||||
['zun', 'tsun'],
|
||||
['cun', 'ts\'un'],
|
||||
['zong', 'tsung'],
|
||||
['cong', 'ts\'ung'],
|
||||
['zi', 'tzu'],
|
||||
['ci', 'tz\'u'],
|
||||
['wa', 'wa'],
|
||||
['wai', 'wai'],
|
||||
['wan', 'wan'],
|
||||
['wang', 'wang'],
|
||||
['wei', 'wei'],
|
||||
['wen', 'wen'],
|
||||
['weng', 'weng'],
|
||||
['wo', 'wo'],
|
||||
['wu', 'wu'],
|
||||
['ya', 'ya'],
|
||||
['yai', 'yai'],
|
||||
['yang', 'yang'],
|
||||
['yao', 'yao'],
|
||||
['ye', 'yeh'],
|
||||
['yan', 'yen'],
|
||||
['yin', 'yin'],
|
||||
['ying', 'ying'],
|
||||
['yo', 'yo'],
|
||||
['you', 'yu'],
|
||||
['yu', 'yü'],
|
||||
['yuan', 'yüan'],
|
||||
['yue', 'yüeh'],
|
||||
['yun', 'yün'],
|
||||
['yong', 'yung'],
|
||||
|
||||
['chua', 'ch`ua'],
|
||||
['dei', 'tei'],
|
||||
['den', 'ten'],
|
||||
['diang', 'tiang'],
|
||||
['ei', 'ei'],
|
||||
['eng', 'eng'],
|
||||
['gei', 'kei'],
|
||||
['lia', 'lia'],
|
||||
['lo', 'lo'],
|
||||
['lüan', 'lüan'],
|
||||
['lvan', 'lüan'],
|
||||
['lüe', 'lüeh'],
|
||||
['lve', 'lüeh'],
|
||||
['lün', 'lün'],
|
||||
['lvn', 'lün'],
|
||||
['me', 'me'],
|
||||
['ne', 'ne'],
|
||||
['nia', 'nia'],
|
||||
['nun', 'nun'],
|
||||
['nüe', 'nüeh'],
|
||||
['nve', 'nüeh'],
|
||||
['o', 'o'],
|
||||
['sei', 'sei'],
|
||||
['shei', 'shei'],
|
||||
['shong', 'shung'],
|
||||
['zhei', 'chei'],
|
||||
]
|
||||
_convert_table.sort(key=lambda x: len(x[0]), reverse=True)
|
||||
|
||||
# https://www.mysmth.net/nForum/#!article/Linguistics/4991
|
||||
_initial_table = [
|
||||
['b', 'p'],
|
||||
['p', 'p\''],
|
||||
['m', 'm'],
|
||||
['f', 'f'],
|
||||
['d', 't'],
|
||||
['t', 't\''],
|
||||
['n', 'n'],
|
||||
['l', 'l'],
|
||||
['g', 'g'],
|
||||
['k', 'k\''],
|
||||
['h', 'h'],
|
||||
['j', 'ch'],
|
||||
['q', 'ch\''],
|
||||
['x', 'hs'],
|
||||
['zh', 'ch'],
|
||||
['ch', 'ch\''],
|
||||
['sh', 'sh'],
|
||||
['r', 'j'],
|
||||
['z', 'ts'],
|
||||
['c', 'ts\''],
|
||||
['s', 's'],
|
||||
]
|
||||
_initial_table.sort(key=lambda x: len(x[0]), reverse=True)
|
||||
_tone_table = [
|
||||
['i', 'i'],
|
||||
['u', 'u'],
|
||||
['ü', 'ü'],
|
||||
['v', 'ü'],
|
||||
['a', 'a'],
|
||||
['ia', 'ia'],
|
||||
['ua', 'ua'],
|
||||
['o', 'o'],
|
||||
['uo', 'o'],
|
||||
['e', 'e'],
|
||||
['ie', 'ieh'],
|
||||
['üe', 'üeh'],
|
||||
['ve', 'üeh'],
|
||||
['ai', 'ei'],
|
||||
['uei', 'ui'],
|
||||
['ao', 'ao'],
|
||||
['iao', 'iao'],
|
||||
['ou', 'ou'],
|
||||
['iou', 'iu'],
|
||||
['an', 'an'],
|
||||
['ian', 'ien'],
|
||||
['uan', 'uan'],
|
||||
['üan', 'üan'],
|
||||
['van', 'üan'],
|
||||
['en', 'en'],
|
||||
['in', 'in'],
|
||||
['uen', 'un'],
|
||||
['ün', 'ün'],
|
||||
['vn', 'ün'],
|
||||
['ang', 'ang'],
|
||||
['iang', 'iang'],
|
||||
['uang', 'uang'],
|
||||
['eng', 'eng'],
|
||||
['ing', 'ing'],
|
||||
['ueng', 'ueng'],
|
||||
['ong', 'ung'],
|
||||
['iong', 'iung'],
|
||||
['ê', 'eh'],
|
||||
['er', 'erh'],
|
||||
]
|
||||
_tone_table.sort(key=lambda x: len(x[0]), reverse=True)
|
||||
_except_table = [
|
||||
['zhi', 'chih'],
|
||||
['chi', 'ch\'ih'],
|
||||
['shi', 'shih'],
|
||||
['ri', 'jih'],
|
||||
['zi', 'tzu'],
|
||||
['ci', 'tz\'u'],
|
||||
['si', 'ssu'],
|
||||
['guo', 'guo'],
|
||||
['kuo', 'k\'uo'],
|
||||
['huo', 'huo'],
|
||||
['luo', 'luo'],
|
||||
['jue', 'chüeh'],
|
||||
['que', 'ch\'üeh'],
|
||||
['xue', 'hsüeh'],
|
||||
]
|
||||
_except_table.sort(key=lambda x: len(x[0]), reverse=True)
|
||||
|
||||
|
||||
def to_wade_glides(pinyin, **kwargs):
|
||||
pinyin = replace_symbol_to_no_symbol(pinyin).replace('v', 'ü')
|
||||
|
||||
whole_converted = _convert_whole(pinyin, _except_table)
|
||||
if whole_converted != pinyin:
|
||||
return _fixed_result(whole_converted)
|
||||
whole_converted = _convert_whole(pinyin, _convert_table)
|
||||
if whole_converted != pinyin:
|
||||
return _fixed_result(whole_converted)
|
||||
|
||||
initials = get_initials(pinyin, strict=False)
|
||||
tones = pinyin[len(initials):]
|
||||
|
||||
initials = _convert_whole(initials, _initial_table)
|
||||
tones = _convert_whole(tones, _tone_table)
|
||||
|
||||
return _fixed_result('{}{}'.format(initials, tones))
|
||||
|
||||
|
||||
def _fixed_result(pinyin):
|
||||
return pinyin.replace('ü', 'v')
|
||||
|
||||
|
||||
def _convert_whole(chars, table):
|
||||
for pair in table:
|
||||
f, r = pair
|
||||
if f == chars:
|
||||
return r
|
||||
|
||||
return chars
|
||||
|
||||
|
||||
register(Style.WADEGILES, func=to_wade_glides)
|
||||
@@ -0,0 +1,12 @@
|
||||
from typing import Any, List, Dict, Text
|
||||
|
||||
_convert_table = ... # type: List[List[Text]]
|
||||
|
||||
_initial_table = ... # type: List[List[Text]]
|
||||
|
||||
_tone_table = ... # type: List[List[Text]]
|
||||
|
||||
_except_table = ... # type: List[List[Text]]
|
||||
|
||||
|
||||
def to_wade_glides(pinyin: Text, **kwargs: Any) -> Text: ...
|
||||
@@ -0,0 +1,103 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import unicode_literals
|
||||
from argparse import ArgumentParser
|
||||
from functools import partial
|
||||
import re
|
||||
import sys
|
||||
|
||||
from pypinyin.compat import PY2
|
||||
from pypinyin.style._constants import (
|
||||
PHONETIC_SYMBOL_DICT, PHONETIC_SYMBOL_DICT_KEY_LENGTH_NOT_ONE
|
||||
)
|
||||
from pypinyin.contrib.tone_convert import (
|
||||
to_normal,
|
||||
to_tone,
|
||||
to_tone2,
|
||||
to_tone3,
|
||||
# to_initials,
|
||||
# to_finals,
|
||||
# to_finals_tone,
|
||||
# to_finals_tone2,
|
||||
# to_finals_tone3,
|
||||
)
|
||||
|
||||
re_pinyin = re.compile(
|
||||
r'(?m)(^|\s|,)([1-5a-zêü{0}]+)'.format(
|
||||
re.escape(
|
||||
''.join(x for x in PHONETIC_SYMBOL_DICT if len(x) == 1)
|
||||
)
|
||||
)
|
||||
)
|
||||
ACTIONS = {
|
||||
'to_normal': to_normal,
|
||||
'to_tone': to_tone,
|
||||
'to_tone2': to_tone2,
|
||||
'to_tone3': to_tone3,
|
||||
# 'to_initials': to_initials,
|
||||
# 'to_finals': to_finals,
|
||||
# 'to_finals_tone': to_finals_tone,
|
||||
# 'to_finals_tone2': to_finals_tone2,
|
||||
# 'to_finals_tone3': to_finals_tone3,
|
||||
}
|
||||
|
||||
|
||||
def re_sub(action, match_obj):
|
||||
func = ACTIONS[action]
|
||||
converted = func(match_obj.group(2))
|
||||
return '{0}{1}'.format(match_obj.group(1), converted)
|
||||
|
||||
|
||||
def prepare(input):
|
||||
for k, v in PHONETIC_SYMBOL_DICT_KEY_LENGTH_NOT_ONE.items():
|
||||
if k in input:
|
||||
input = input.replace(k, v)
|
||||
return input
|
||||
|
||||
|
||||
def convert(action, args):
|
||||
inputs = args.inputs
|
||||
for item in inputs:
|
||||
item = prepare(item)
|
||||
result = re_pinyin.sub(lambda m: re_sub(action, m), item)
|
||||
print(result)
|
||||
|
||||
|
||||
def get_parser():
|
||||
parser = ArgumentParser()
|
||||
|
||||
if PY2 or sys.version_info < (3, 7):
|
||||
subparser = parser.add_subparsers()
|
||||
else:
|
||||
subparser = parser.add_subparsers(required=True, title='subcommands')
|
||||
|
||||
for key in ACTIONS.keys():
|
||||
name = key.replace('_', '-')
|
||||
func = partial(convert, key)
|
||||
p = subparser.add_parser(
|
||||
name,
|
||||
help='call pypinyin.contrib.tone_convert.{}() with inputs'.format(key))
|
||||
p.set_defaults(func=func)
|
||||
p.add_argument('inputs', nargs='+')
|
||||
|
||||
return parser
|
||||
|
||||
|
||||
def main(argv):
|
||||
argv = argv[:]
|
||||
|
||||
if not sys.stdin.isatty():
|
||||
pipe_data = sys.stdin.read().strip()
|
||||
else:
|
||||
pipe_data = ''
|
||||
if pipe_data:
|
||||
argv.append(pipe_data)
|
||||
|
||||
parser = get_parser()
|
||||
args = parser.parse_args(argv)
|
||||
args.func(args)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main(sys.argv[1:])
|
||||
@@ -0,0 +1,16 @@
|
||||
from argparse import ArgumentParser, Namespace
|
||||
import re
|
||||
from typing import Union, Text, ByteString, Dict, Any, List
|
||||
|
||||
re_pinyin = ... # type: Any
|
||||
ACTIONS = ... # type: Dict[Text, Any]
|
||||
|
||||
def re_sub(action: Text, match_obj: re.Match[Text]) -> Text: ...
|
||||
|
||||
def prepare(input: Text) -> Text: ...
|
||||
|
||||
def convert(action: Text, args: Namespace) -> None: ...
|
||||
|
||||
def get_parser() -> ArgumentParser: ...
|
||||
|
||||
def main(argv: List[Text]) -> None: ...
|
||||
@@ -0,0 +1,34 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
# 用于向后兼容,TODO: 废弃
|
||||
from pypinyin.seg.simpleseg import simple_seg # noqa
|
||||
from pypinyin.style._tone_convert import tone2_to_tone
|
||||
|
||||
|
||||
# 用于向后兼容,TODO: 废弃
|
||||
def _replace_tone2_style_dict_to_default(string):
|
||||
return tone2_to_tone(string)
|
||||
|
||||
|
||||
def _remove_dup_items(lst, remove_empty=False):
|
||||
new_lst = []
|
||||
for item in lst:
|
||||
if remove_empty and not item:
|
||||
continue
|
||||
if item not in new_lst:
|
||||
new_lst.append(item)
|
||||
return new_lst
|
||||
|
||||
|
||||
def _remove_dup_and_empty(lst_list):
|
||||
new_lst_list = []
|
||||
for lst in lst_list:
|
||||
lst = _remove_dup_items(lst, remove_empty=True)
|
||||
if lst:
|
||||
new_lst_list.append(lst)
|
||||
else:
|
||||
new_lst_list.append([''])
|
||||
|
||||
return new_lst_list
|
||||
@@ -0,0 +1,10 @@
|
||||
from typing import List, Text
|
||||
|
||||
|
||||
def _replace_tone2_style_dict_to_default(string: Text) -> Text: ...
|
||||
|
||||
|
||||
def _remove_dup_items(lst: List[Text]) -> List[Text]: ...
|
||||
|
||||
|
||||
def _remove_dup_and_empty(lst_list: List[List[Text]]) -> List[List[Text]]: ...
|
||||
Reference in New Issue
Block a user