平方X

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 3750|回复: 0

正则匹配带声调的汉语拼音

[复制链接]

414

主题

709

帖子

3657

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
3657
QQ
发表于 2017-9-27 17:11:14 | 显示全部楼层 |阅读模式
[md]

>本文由平方X发表于平方X网,转载请注明出处。[http://blog.pingfangx.com/2387.html](http://blog.pingfangx.com/2387.html)


如果不带声调的话,还可以将声母、韵母列出来,可是加上声调就多了啊。  
于是想只用声母匹配
```
initial_consonant = 'zh|ch|sh|[bpmfdtnlgkhjqxzcsryw]'
p_pinyin = re.compile(r'%s.*' % initial_consonant)
```
这样后面的话,贪婪会把整串拼音都匹配了,懒惰又只能匹配一个字母

改为后面不能是声母,这里因为要取字符,所有不能用(?!),用的[^]
```
initial_consonant = 'zh|ch|sh|[bpmfdtnlgkhjqxzcsryw]'
p_pinyin = re.compile(r'%s[^bpmfdtnlgkhjqxzcsryw]+' % initial_consonant)
```
还是不行,后面也可能会包含声母的,如 dian 还包含 n

于是改为逆向的匹配,不知道正则有没有逆向匹配的方法,自己没找到,只好逆向截取字符串进行匹较。
```
initial_consonant = 'zh|ch|sh|[bpmfdtnlgkhjqxzcsryw]'
p_pinyin = re.compile(r'(%s)(?!%s)+' % (initial_consonant, initial_consonant))
```
这样匹配时,遇到 zhi、chi、shi 只能匹配出 hi,于是改为
```
p_pinyin = re.compile(r'(?<![zcs])(%s)(?!%s)+' % (initial_consonant, initial_consonant))
```
可是还是不行,因为逆向截取的时候并没有截到前面的 zcs ,所以只能再加一个字符串截取到它之前。

最终结果
```

    @staticmethod
    def split_pinyin(pinyin):
        """分割拼音"""
        result = list()
        while pinyin:
            pinyin, last_pinyin = PinyinFilter.get_last_pinyin(pinyin)
            result.insert(0, last_pinyin)
        return result

    @staticmethod
    def get_last_pinyin(pinyin):
        """
        获取最后一个拼音,返回除最后一个拼音外剩下的拼音,以及最后一个拼音
        :param pinyin: 要截取的字符串
        :return: (剩余拼音,最后一个拼音)
        """
        initial_consonant = 'zh|ch|sh|[bpmfdtnlgkhjqxzcsryw]'
        # 前面是声母,后面不能跟声母
        p_pinyin = re.compile(r'(?<![zcs])(%s)(?!%s)+' % (initial_consonant, initial_consonant))
        # 如zhi chi shi ,要加上这个判断才能匹配出 zhi ,否则会直接认为是 hi
        p_pinyin2 = re.compile(r'[^zcs]')
        length = len(pinyin)
        # 从1开始,因为一个声母不算拼音
        for i in range(1, length):
            if i == length - 1:
                # 最后一个单词了
                return None, pinyin
            else:
                sub_word1 = pinyin[-i - 1:]
                sub_word2 = pinyin[-i - 2:-i - 1]
                if re.match(p_pinyin, sub_word1) and re.match(p_pinyin2, sub_word2):
                    return pinyin[:length - len(sub_word1)], sub_word1

```

# Talk is cheap
[相关源码](https://github.com/pingfangx/Pyt ... /pinyin_splitter.py)  

相关博文  
[大观楼长联原文、注音及释义](http://blog.pingfangx.com/2386.html)

[/md]
我是平方X~
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|手机版|Archiver|平方X ( 冀ICP备14018164号 )

GMT+8, 2024-11-22 01:28 , Processed in 0.094207 second(s), 21 queries .

技术支持:Powered by Discuz!X3.4  © 2001-2013 Comsenz Inc.

版权所有:Copyright © 2014-2018 平方X www.pingfangx.com All rights reserved.

快速回复 返回顶部 返回列表