_utils.py 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. # -*- coding: utf-8 -*-
  2. from __future__ import unicode_literals
  3. from pypinyin.standard import convert_finals
  4. from pypinyin.style._constants import (
  5. _INITIALS, _INITIALS_NOT_STRICT, _FINALS,
  6. RE_PHONETIC_SYMBOL, PHONETIC_SYMBOL_DICT,
  7. PHONETIC_SYMBOL_DICT_KEY_LENGTH_NOT_ONE,
  8. RE_NUMBER
  9. )
  10. def get_initials(pinyin, strict):
  11. """获取单个拼音中的声母.
  12. :param pinyin: 单个拼音
  13. :type pinyin: unicode
  14. :param strict: 是否严格遵照《汉语拼音方案》来处理声母和韵母
  15. :return: 声母
  16. :rtype: unicode
  17. """
  18. if strict:
  19. _initials = _INITIALS
  20. else:
  21. _initials = _INITIALS_NOT_STRICT
  22. for i in _initials:
  23. if pinyin.startswith(i):
  24. return i
  25. return ''
  26. def get_finals(pinyin, strict):
  27. """获取单个拼音中的韵母.
  28. :param pinyin: 单个拼音,无声调拼音
  29. :type pinyin: unicode
  30. :param strict: 是否严格遵照《汉语拼音方案》来处理声母和韵母
  31. :return: 韵母
  32. :rtype: unicode
  33. """
  34. if strict:
  35. pinyin = convert_finals(pinyin)
  36. initials = get_initials(pinyin, strict=strict) or ''
  37. # 按声母分割,剩下的就是韵母
  38. finals = pinyin[len(initials):]
  39. # 处理既没有声母也没有韵母的情况
  40. if strict and finals not in _FINALS:
  41. # 处理 y, w 导致误判的问题,比如 yo
  42. initials = get_initials(pinyin, strict=False)
  43. finals = pinyin[len(initials):]
  44. if finals in _FINALS:
  45. return finals
  46. return ''
  47. # ń, ḿ
  48. if not finals and not strict:
  49. return pinyin
  50. return finals
  51. def replace_symbol_to_number(pinyin):
  52. """把声调替换为数字"""
  53. def _replace(match):
  54. symbol = match.group(0) # 带声调的字符
  55. # 返回使用数字标识声调的字符
  56. return PHONETIC_SYMBOL_DICT[symbol]
  57. # 替换拼音中的带声调字符
  58. value = RE_PHONETIC_SYMBOL.sub(_replace, pinyin)
  59. for symbol, to in PHONETIC_SYMBOL_DICT_KEY_LENGTH_NOT_ONE.items():
  60. value = value.replace(symbol, to)
  61. return value
  62. def replace_symbol_to_no_symbol(pinyin):
  63. """把带声调字符替换为没有声调的字符"""
  64. value = replace_symbol_to_number(pinyin)
  65. return RE_NUMBER.sub('', value)
  66. def has_finals(pinyin):
  67. """判断是否有韵母"""
  68. # 鼻音: 'm̄', 'ḿ', 'm̀', 'ń', 'ň', 'ǹ ' 没有韵母
  69. for symbol in ['m̄', 'ḿ', 'm̀', 'ń', 'ň', 'ǹ']:
  70. if symbol in pinyin:
  71. return False
  72. return True