• 装13失败后,我决定使用Python为生僻字批量注音


    装13的冷场

    “龙生九子,各不相同…”
    囚牛、睚眦、嘲风、蒲牢、狻猊、霸下、狴犴、负屃、螭吻。

    都说提笔忘字丢人,可至少还有提笔的机会。随着信息化时代的普及,原来越多的人成了半文盲。怎么说?电脑前打字敲的一二一,可提起笔来就忘字。从前特别喜欢钢笔,笔袋里放的凌美、百利、永生、英雄一堆,买的北碳、毕加索、派克、百利金各式牌子的墨水。结果感觉半年多都没动过这些陈年老货了。
    下午聊天装13说到龙生九子,本来吹得正欢,结果朋友问老七 bì àn怎么写,然后…瞬间懵逼了,这个13装的有点冷场啊。
    最近项目有些忙,晚上构思该写点什么。想到下午的尴尬,决定发一篇之前写的Python为生僻字歌词注音的文章。

    抖音配乐—生僻字

    首次听到生僻字就是从抖音了,随着生僻字配乐使用的人越来越多,很多人翻唱、模仿甚至有讲解成语出处和寓意的段子,可谓百家争鸣。
    但,有一类视频很不讨喜,就是把歌词用谐音字代替,好让人一眼认识。
    如果是那些哈韩哈日的朋友们,想唱歌但又没有语言基础,那你配上谐音的字没毛病。可歌词中的成语和汉字就是老祖宗传下来的文化,你却用谐音字去让自己容易辨识,不觉得脸红吗?
    如果不认识,你可以查字典,找度娘,然后标注上拼音啊!即娱乐又长知识了。
    当然有人觉得这样一个一个的查太麻烦,那是因为——你不会Python啊!
    今天,我就来教教你们,怎么把文本内容自动标注拼音。

    Python的拼音模块

    Python的模块库API,每次进去习惯第一动作,就是右键翻译为中文。(好羞愧,个人太爱国了,所以一直排斥学英语,好不要脸的借口…)可Python的拼音模块不需要这么做,因为涉及拼音等模块肯定和中文有关系,文档自然是中文的喽。
    那么Python的拼音模块是什么? pypinyin

    • 特性

      • 根据词组智能匹配最正确的拼音。

      • 支持多音字。

      • 简单的繁体支持, 注音支持。

      • 支持多种不同拼音/注音风格。

    • 安装
      pip install pypinyin

    • 使用示例

    >>> from pypinyin import pinyin, lazy_pinyin, Style
    >>> 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, heteronym=True)
    [['zho1ng', 'zho4ng'], ['xi1n']]
    >>> pinyin('中心', style=Style.BOPOMOFO)  # 注音风格
    [['ㄓㄨㄥ'], ['ㄒㄧㄣ']]
    >>> pinyin('中心', style=Style.CYRILLIC)  # 俄语字母风格
    [['чжун1'], ['синь1']]
    >>> lazy_pinyin('中心')  # 不考虑多音字的情况
    ['zhong', 'xin']
    # Python 3(Python 2 下把 '中心' 替换为 u'中心' 即可):

    实现分析

    起初想着,既然有了这个强大的拼音模块,那么文本批量添加拼音,岂不是分分钟的事情了吗?然后,打脸接踵而来!
    首先,要实现文字上一一对应的标注拼音,每个字与拼音的长度肯定不同,没办法对其。如果要对其,就得将文字进行拆分,字与字之间添加间距。有人说简单啊,每个字的拼音最多不过6位,那我们使用列表解析式[i.just(6) for i in line]不就完了?
    听起来没毛病,但是…

    • 歌词也有语气词啊,这句Wu 又双叒叕你直接按照字符串拆开成了什么鬼?

    • 一个中文在文本中占两个字符的长度,如果对齐的话,还需要识别中文和英文字符!

    • 有效字符的辨识,Wu被认为是是个有效字段,模块会对其进行合并

      pinyin(‘Wu 又双叒叕’) —>[[‘Wu ‘], [‘yòu’], [‘shuāng’], [‘ruò’], [‘zhuó’]]

    中文识别

    本来考虑使用正则去判断中文的,因为网上查到正则的匹配中文是[u4e00-u9fa5],简单测试了下,貌似没毛病
    然后…代码都快写完了发现有些生僻字不再这个范围内,我擦!

    'u4e00'<='生'<='u9fa5'
    True
    'u4e00'<='僻'<='u9fa5'
    True
    'u4e00'<='字'<='u9fa5'
    True
    'u4e00'<='㙓'<='u9fa5'
    False

    解决办法

    针对正则匹配问题,深入去研究,就脱离了学Python的初衷,即便解决了也收获甚微,不如换个思路。
    utf-8字符编码下,一个中文字符占3个字节,但是字符的长度仅为1,那么解析中文的方式是否可以变通为:
    len(bytes(str,'utf-8) == 3 and len(string) == 1)
    关于文本书写,我们判断中文后,如果是汉字str.ljust(5),否则str.ljust(6)不就行了(因为一个汉字占两个字符长度)。

    代码实现

    # -*- coding: utf-8 -*-
    # @Author  : 王翔
    # @公众号   : 清风Python
    
    # @WeChat  : King_Uranus
    
    # @Date    : 2019/9/6 01:33
    # Software : PyCharm
    # version  :Python 3.7.3
    # @File    : TextAddPinyin.py
    
    from pypinyin import pinyin
    import re
    
    
    class ChangePinyin:
        def __init__(self, filename):
            self.file = filename
            self.lyric = self.read_file()
            self.pinyin = []
    
        def read_file(self):
            with open(self.file, encoding='utf-8') as f:
                return f.readlines()
    
        def write_file(self):
            with open('New_%s' % self.file, 'w', encoding='utf-8') as f:
                print(self.lyric)
                for line in self.lyric:
                    # print(line)
                    if line.strip() == '':
                        continue
                    _new_line = re.sub(r's', '', line)
                    # 行内容转拼音
                    _pinyin = ''.join(map(lambda x: x[0].ljust(6), pinyin(_new_line)))
                    # 根据中英文,将行内容进行字符与汉字的拆分
                    _lyric = self.split_words(_new_line)
                    f.write('%s
    %s
    ' % (_pinyin, _lyric))
    
        @staticmethod
        def split_words(words):
            word_list = ""
            tmp = ""
            for string in words:
                if len(bytes(string, 'utf-8')) == 3 and len(string) == 1:
                    if tmp != '':
                        word_list += tmp.ljust(6)
                        tmp = ""
                    word_list += string.ljust(5)
                else:
                    tmp += string
            return word_list
    
    
    if __name__ == '__main__':
        Main = ChangePinyin('lyric.txt')
        Main.write_file()

    看看最后的实现效果吧,是不是格式很工整!

    录屏软件为LICEcap

    它是一款屏幕录制工具,支持导出 GIF 动画图片格式,轻量级、使用简单,录制过程中可以随意改变录屏范围。
    好了,今天的内容就到这里,希望大家喜欢,如果觉得文章有用,记得关注支持我啊。

    The End

    OK,今天的内容就到这里,如果觉得内容对你有所帮助,欢迎点赞。
    期待你关注我的公众号清风Python,如果觉得不错,希望能动动手指转发给你身边的朋友们。

    作者:清风Python

  • 相关阅读:
    如果你正在找工作,也许这七个方法会帮到你
    WebSocket 浅析
    关系数据库涉及中的范式与反范式
    MySQL字段类型与合理的选择字段类型
    ER图,数据建模与数据字典
    详解慢查询
    MySQL的最佳索引攻略
    后端技术演进
    MySQL主从复制(BinaryLog)
    MySQL读写分离
  • 原文地址:https://www.cnblogs.com/2020-zhy-jzoj/p/13165465.html
Copyright © 2020-2023  润新知