如何使用正则表达式组读取cedict(空格分隔文件)?

时间:2017-01-25 05:43:09

标签: python regex dictionary unicode nlp

CEDICT是中文文本分析的资源

文件明文文件如下所示:

# CC-CEDICT
# Community maintained free Chinese-English dictionary.
# 
# Published by MDBG
% % [pa1] /percent (Tw)/
21三體綜合症 21三体综合症 [er4 shi2 yi1 san1 ti3 zong1 he2 zheng4] /trisomy/Down's syndrome/
3C 3C [san1 C] /abbr. for computers, communications, and consumer electronics/China Compulsory Certificate (CCC)/
3P 3P [san1 P] /(slang) threesome/
A A [A] /(slang) (Tw) to steal/

文件有4列,用空格分隔。第4次之后的任何空格都被视为一个空格。需要跳过以#开头的行。

E.g。对于该行:

  

3C 3C [san1 C] / abbr。计算机,通信和消费电子/中国强制认证(CCC)/

列中的内容为

  • 3C
  • 3C
  • [san1 C]
  • /缩写。计算机,通信和消费电子/中国强制认证(CCC)/

目前正在尝试使用str.splitre.findall的混合以及str.startswith()的跳过行来尝试阅读该文件,即:

import re
from collections import namedtuple


DictEntry = namedtuple('Dictionary', 'traditional simplified pinyin glosses')

dictfile = 'cedict_ts.u8'
cedict = {}

with open(dictfile, 'r', encoding='utf8') as fin:
    for line in fin:
        if line.startswith('#'):
            continue
        # Note: lines are NOT separated by tabs.
        line = line.strip()
        trad, sim, *stuff = line.split()
        pinyin = re.findall(r'\[([^]]*)\]',line)[0]
        glosses = re.findall(r'\/.*\/', line)[0].strip('/').split('/')
        entry = DictEntry(traditional=trad, simplified=sim, pinyin=pinyin, glosses=glosses)
        cedict[sim] = entry

看起来str和regex操作可以简化为单个正则表达式,并且可以使用组提取列。 如何使用正则表达式组读取cedict(空格分隔文件)?

我也尝试过4组这个正则表达式:

(.*)\s(.*)\s(\[([^]]*)\])\s(\/.*\/)

但不知何故,第一个(.*)\s是贪婪的,它抓住整行:https://regex101.com/r/1c0O0E/1

我试过这个:

.+\s(\[([^]]*)\])\s(\/.*\/)

第一个.+\s抓住,直至看到[。但这意味着我必须使用str.split()来获得前2列。

1 个答案:

答案 0 :(得分:1)

使用"非空间" (\S)而不只是"任何事情" (.):

^(\S+)\s+(\S+)\s+(\[[^]]+\])\s+(\/.*\/)$

我还添加了文本开头和测试结束锚(^& $),以排除任何与所需模式不匹配的行(例如注释行)。

演示:https://regex101.com/r/0QNzVi/3