首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何标记化拼音,最好使用嵌套的、重叠的正则表达式组?

如何标记化拼音,最好使用嵌套的、重叠的正则表达式组?
EN

Stack Overflow用户
提问于 2019-02-10 03:08:52
回答 1查看 93关注 0票数 0

我正在尝试标记化一个中文拼音符号(无声调)。考虑以下代码:

代码语言:javascript
运行
复制
finals = ['a',
        'o',
        'e',
        'ai',
        'ei',
        'ao',
        'ou',                                                                                                                                                                       
        'an',                                                                                                                                                                       
        'ang',
        'en',
        'eng',
        'er',
        'u',
        'ua',
        'uo',
        'uai',
        'ui',
        'uan',
        'uang',
        'un',
        'ueng',
        'ong',
        'i',
        'i',
        'ia',
        'ie',
        'iao',
        'iu',
        'ian',
        'iang',
        'in',
        'ing',
        'ü',
        'üe',
        'üan',
        'ün',
        'iong']
initials = ['p',
          'm',
          'f',
          'd',
          't',
          'n',
          'l',
          'g',
          'k',
          'h',
          'j',
          'q',
          'x',
          'z',
          'h',
          'c',
          'h',
          's',
          'h',
          'r',
          'z',
          'c',
          's']
others = ['a',
        'o',
        'e',
        'ai',
        'ei',
        'ao',
        'ou',
        'an',
        'ang',
        'en',
        'eng',
        'er',
        'wu',
        'wa',
        'wo',
        'wai',
        'wei',
        'wan',
        'wang',
        'wen',
        'weng',
        'yi',
        'ya',
        'ye',
        'yao',
        'you',
        'yan',
        'yang',
        'yin',
        'ying',
        'yu',
        'yue',
        'yuan',
        'yun',
        'yong']

r = '^((%s)(%s)|%s)+$' % ('|'.join(initials), '|'.join(finals), '|'.join(others))
import re
m = re.match(r, 'yinwei')
print(m.groups())

我希望得到['yin','wei'] (两个连续的外部组),但由于某种原因只得到了'wei‘。为什么这段代码不能工作以及如何修复它?我还尝试了以下方法,但它随机给出了['yin', 'wei']['yi', 'wei]

代码语言:javascript
运行
复制
import regex
r = '|'.join({i + f for i in initials for f in finals}.union(set(others)))
print(regex.findall(r, 'yinwei'))

编辑:由于ekhumuro的回答,我本来打算接受它是4963691的副本,但它不能以bangongshi作为输入--我们得到的是['bang', 'o', 'shi'],而不是['ban','gong','shi']。正因为如此,我希望这个问题与this one分开考虑。

EN

Stack Overflow用户

发布于 2019-02-10 04:27:46

当与+之类的运算符一起使用时,re模块不会累加组。在您的示例中,它将首先匹配'yin',然后匹配'wei' -但它将只保留最后一组匹配的组(因此m.groups()将只返回['wei', None, None])。但是,您的正则表达式仍将正确地获得整个匹配-因此m.group()将返回'yinwei'

列表中的元素似乎不会产生任何重叠的组合。也就是说:在others中没有重复的initials[n] + finals[n]。然而,每个列表中都有重叠的元素(例如others中的yi|yin|ying ),但这可以通过按长度降序对列表进行排序来解决。

这意味着你可以很容易地将拼音单词拆分成它的元素,如下所示:

代码语言:javascript
运行
复制
import re

initials.sort(key=len, reverse=True)
finals.sort(key=len, reverse=True)
others.sort(key=len, reverse=True)

r = '(?:%s)(?:%s)|(?:%s)' % ('|'.join(initials), '|'.join(finals), '|'.join(others))
print(re.findall(r, 'yinwei'))

输出:

代码语言:javascript
运行
复制
['yin', 'wei']

更新

看过reliable source之后,你解析拼音的方法似乎太简单了。table of combinations表明并非所有的可能性都是有效的。它还表明,一些组合是模棱两可的(从纯粹的句法角度来看)。例如,liang可以解析为[l + iang][l + i], [ang]。而且,并不是所有的延续都是有效的,所以需要一些回溯断言。这表明,需要一种更复杂的方法,而不是简单地从左到右顺序匹配。经过一些搜索,我发现了前面的一个问题,似乎涵盖了相同的问题:

然而,使用单个regexp来解决这个问题似乎并不简单,所以您可能需要考虑寻找一个知道如何处理所有棘手的边缘情况的第三方库。

票数 1
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54609740

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档