bopomofo.py 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. # -*- coding: utf-8 -*-
  2. """BOPOMOFO 相关的几个拼音风格实现:
  3. Style.BOPOMOFO
  4. Style.BOPOMOFO_FIRST
  5. """
  6. from __future__ import unicode_literals
  7. import re
  8. from pypinyin.constants import Style
  9. from pypinyin.style import register
  10. from pypinyin.style._constants import RE_TONE3
  11. from pypinyin.style._utils import replace_symbol_to_number
  12. # 注音转换表
  13. BOPOMOFO_REPLACE = (
  14. (re.compile(r'^m(\d)$'), 'mu\\1'), # 呣
  15. (re.compile(r'^n(\d)$'), 'N\\1'), # 嗯
  16. (re.compile(r'^r5$'), 'er5'), # 〜兒
  17. (re.compile(r'iu'), 'iou'),
  18. (re.compile(r'ui'), 'uei'),
  19. (re.compile(r'ong'), 'ung'),
  20. (re.compile(r'^yi?'), 'i'),
  21. (re.compile(r'^wu?'), 'u'),
  22. (re.compile(r'iu'), 'v'),
  23. (re.compile(r'^([jqx])u'), '\\1v'),
  24. (re.compile(r'([iuv])n'), '\\1en'),
  25. (re.compile(r'^zhi?'), 'Z'),
  26. (re.compile(r'^chi?'), 'C'),
  27. (re.compile(r'^shi?'), 'S'),
  28. (re.compile(r'^([zcsr])i'), '\\1'),
  29. (re.compile(r'ai'), 'A'),
  30. (re.compile(r'ei'), 'I'),
  31. (re.compile(r'ao'), 'O'),
  32. (re.compile(r'ou'), 'U'),
  33. (re.compile(r'ang'), 'K'),
  34. (re.compile(r'eng'), 'G'),
  35. (re.compile(r'an'), 'M'),
  36. (re.compile(r'en'), 'N'),
  37. (re.compile(r'er'), 'R'),
  38. (re.compile(r'eh'), 'E'),
  39. (re.compile(r'([iv])e'), '\\1E'),
  40. (re.compile(r'([^0-4])$'), '\\g<1>0'),
  41. (re.compile(r'1$'), ''),
  42. )
  43. BOPOMOFO_TABLE = dict(zip(
  44. 'bpmfdtnlgkhjqxZCSrzcsiuvaoeEAIOUMNKGR2340ê',
  45. 'ㄅㄆㄇㄈㄉㄊㄋㄌㄍㄎㄏㄐㄑㄒㄓㄔㄕㄖㄗㄘㄙㄧㄨㄩㄚㄛㄜㄝㄞㄟㄠㄡㄢㄣㄤㄥㄦˊˇˋ˙ㄝ'
  46. ))
  47. class BopomofoConverter(object):
  48. def to_bopomofo(self, pinyin, **kwargs):
  49. pinyin = self._pre_convert(pinyin)
  50. # 查表替换成注音
  51. for find_re, replace in BOPOMOFO_REPLACE:
  52. pinyin = find_re.sub(replace, pinyin)
  53. pinyin = ''.join(BOPOMOFO_TABLE.get(x, x) for x in pinyin)
  54. return pinyin
  55. def to_bopomofo_first(self, pinyin, **kwargs):
  56. pinyin = self.to_bopomofo(pinyin, **kwargs)
  57. return pinyin[0]
  58. def _pre_convert(self, pinyin):
  59. # 用数字表示声调
  60. pinyin = replace_symbol_to_number(pinyin)
  61. # 将声调数字移动到最后
  62. return RE_TONE3.sub(r'\1\3\2', pinyin)
  63. converter = BopomofoConverter()
  64. register(Style.BOPOMOFO, func=converter.to_bopomofo)
  65. register(Style.BOPOMOFO_FIRST, func=converter.to_bopomofo_first)