背景介绍:将搜狗词库中 .scel 文件转化为 .txt 文件
- 搜狗词库链接:https://pinyin.sogou.com/dict/
-
搜狗的scel词库就是保存的文本的unicode编码,每两个字节一个字符(中文汉字或者英文字母)找出其每部分的偏移位置即可,主要两部分:
2.1 全局拼音表,貌似是所有的拼音组合,字典序 格式为(index,len,pinyin)的列表 index: 两个字节的整数 代表这个拼音的索引 len: 两个字节的整数 拼音的字节长度 pinyin: 当前的拼音,每个字符两个字节,总长len
2.2 汉语词组表 格式为(same,py_table_len,py_table,{word_len,word,ext_len,ext})的一个列表 same: 两个字节 整数 同音词数量 py_table_len: 两个字节 整数 py_table: 整数列表,每个整数两个字节,每个整数代表一个拼音的索引
word_len:两个字节 整数 代表中文词组字节数长度 word: 中文词组,每个中文汉字两个字节,总长度word_len ext_len: 两个字节 整数 代表扩展信息的长度,好像都是10 ext: 扩展信息 前两个字节是一个整数(不知道是不是词频) 后八个字节全是0 {word_len,word,ext_len,ext} 一共重复same次 同音词 相同拼音表 -
struct函数 -- struct.pack()和struct.unpack()
在转化过程中,主要用到了一个格式化字符串(format strings),用来规定转化的方法和格式。
3.1 struct.pack(fmt,v1,v2,.....)
将v1,v2等参数的值进行一层包装,包装的方法由fmt指定。被包装的参数必须严格符合fmt。最后返回一个包装后的字符串。
3.2 struct.unpack(fmt,string)
顾名思义,解包。比如pack打包,然后就可以用unpack解包了。返回一个由解包数据(string)得到的一个元组(tuple), 即使仅有一个数据也会被解包成元组。其中len(string) 必须等于 calcsize(fmt),这里面涉及到了一个calcsize函数。struct.calcsize(fmt):这个就是用来计算fmt格式所描述的结构的大小。 格式字符串(format string)由一个或多个格式字符(format characters)组成,对于这些格式字符的描述参照Python manual如下:
| Format | C Type | Python |
|---|---|---|
| x | pad byte | no value |
| c | char | string of length |
| b | signed char | integer |
| B | unsigned char | integer |
| h | short | integer |
| H | unsigned short | integer |
| i | int | integer |
| I | unsigned int | long |
| l | long | integer |
| L | unsigned long | long |
| q | long long | long |
| Q | unsigned long long | long |
| f | float | float |
| d | double | float |
| s | char[] | string |
| p | char[] | string |
| P | void * | integer |
下面给出 Python 代码:
import struct
import os
# 拼音表偏移,
startPy = 0x1540;
# 汉语词组表偏移
startChinese = 0x2628;
# 全局拼音表
GPy_Table = {}
# 解析结果
# 元组(词频,拼音,中文词组)的列表
GTable = []
# 原始字节码转为字符串
def byte2str(data):
pos = 0
str = ''
while pos < len(data):
c = chr(struct.unpack('H', bytes([data[pos], data[pos + 1]]))[0])
if c != chr(0):
str += c
pos += 2
return str
# 获取拼音表
def getPyTable(data):
data = data[4:]
pos = 0
while pos < len(data):
index = struct.unpack('H', bytes([data[pos],data[pos + 1]]))[0]
pos += 2
lenPy = struct.unpack('H', bytes([data[pos], data[pos + 1]]))[0]
pos += 2
py = byte2str(data[pos:pos + lenPy])
GPy_Table[index] = py
pos += lenPy
# 获取一个词组的拼音
def getWordPy(data):
pos = 0
ret = ''
while pos < len(data):
index = struct.unpack('H', bytes([data[pos], data[pos + 1]]))[0]
ret += GPy_Table[index]
pos += 2
return ret
# 读取中文表
def getChinese(data):
pos = 0
while pos < len(data):
# 同音词数量
same = struct.unpack('H', bytes([data[pos], data[pos + 1]]))[0]
# 拼音索引表长度
pos += 2
py_table_len = struct.unpack('H', bytes([data[pos], data[pos + 1]]))[0]
# 拼音索引表
pos += 2
py = getWordPy(data[pos: pos + py_table_len])
# 中文词组
pos += py_table_len
for i in range(same):
# 中文词组长度
c_len = struct.unpack('H', bytes([data[pos], data[pos + 1]]))[0]
# 中文词组
pos += 2
word = byte2str(data[pos: pos + c_len])
# 扩展数据长度
pos += c_len
ext_len = struct.unpack('H', bytes([data[pos], data[pos + 1]]))[0]
# 词频
pos += 2
count = struct.unpack('H', bytes([data[pos], data[pos + 1]]))[0]
# 保存
GTable.append((count, py, word))
# 到下个词的偏移位置
pos += ext_len
def scel2txt(file_name):
# 分隔符
print('-' * 60)
# 读取文件
with open(file_name, 'rb') as f:
data = f.read()
print("词库名:", byte2str(data[0x130:0x338])) # .encode('GB18030')
print("词库类型:", byte2str(data[0x338:0x540]))
print("描述信息:", byte2str(data[0x540:0xd40]))
print("词库示例:", byte2str(data[0xd40:startPy]))
getPyTable(data[startPy:startChinese])
getChinese(data[startChinese:])
if __name__ == '__main__':
# scel所在文件夹路径
in_path = "Scel"
fin = [fname for fname in os.listdir(in_path) if fname[-5:] == ".scel"]
for f in fin:
f = os.path.join(in_path, f)
scel2txt(f)
f = open('./Scel/coal_dict.txt', 'w')
for count, py, word in GTable:
f.write(str(count)+ '\t\t\t' + py + '\t\t\t' + word + '\n')
f.close()
得到结果如下:
------------------------------------------------------------
词库名: 东北话大全【官方推荐】
词库类型: 方言
描述信息: 贼拉逗的东北话你一定听过,说起来实在霸气!词库终于出来了,再也不愁打不出来你想说的话,专门为你私人订制哦,还不快去下载!!!
词库示例: 不想嘎哈 老嘎瘩 嗯呐 瞅你咋的 咋地
------------------------------------------------------------
词库名: 史记【官方推荐】
词库类型: 文学
描述信息: 作者司马迁以其“究天人之际,通古今之变,成一家之言”的史识,使《史记》成为中国第一部,也是最出名的纪传体通史。小编整理了书中经典故事、名句、人物等,让你更快打出相关词汇,我在这等你哦~
词库示例: 十表 姬昌 项羽本纪 武王伐纣 虚怀若谷 商鞅变法
------------------------------------------------------------
词库名: 开发大神专用词库【官方推荐】
词库类型: 互联网
描述信息: 程序猿们是不是遨游在代码的海洋里无法自拔?小编知道你们整日找BUG辛苦了,为辅助你们的工作特意奉上专属词库,提高工作效率,畅快打字。欢迎你们前来补充词条哦 !
词库示例: 资源保留 代码 优先级 启动事件 排期 公开测试
------------------------------------------------------------
词库名: 柳宗元诗词【官方推荐】
词库类型: 诗词歌赋
描述信息: 柳宗元,唐朝文学家、散文家和思想家。倡导唐代古文运动。散文论说性强,笔锋犀利,讽刺辛辣。游记写景状物,多所寄托。诗多抒写抑郁悲愤、思乡怀友之情,自成一路。
词库示例: 柳河东 永州八记 捕蛇者说 柳河东集 江雪 小石潭记
------------------------------------------------------------
词库名: 诗经【官方推荐】
词库类型: 诗词歌赋
描述信息: 《诗经》是中国古代诗歌开端,最早的一部诗歌总集,现存305篇(此外有目无诗的6篇,共311篇),分《风》、《雅》、《颂》三部分。《颂》有40篇,《雅》有105篇(《小雅》中有6篇有目无诗,不计算在内),《风》的数量最多,共160篇,合起来是305篇。古人取其整数,常说“诗三百”。
词库示例: 君子好逑 悠哉悠哉 左右采之 琴瑟友之 施于中谷 黄鸟于飞
GitHub项目链接:
scel文件:https://github.com/CQiang27/Spark_Python/tree/master/Scel
Python源码:https://github.com/CQiang27/Spark_Python/blob/master/scel_TR_txt.ipynb
参考文献:
[1] 多个.scel合并为同一dict,并去重,https://blog.csdn.net/leitouguan8655/article/details/82834517
[2] scel2txt 搜狗scel格式转txt python3,https://blog.csdn.net/cFarmerReally/article/details/78149648
[3] Python中struct.pack()和struct.unpack()用法详细说明,http://www.php.cn/python-tutorials-356984.html
这篇博客介绍了如何使用Python将搜狗词库的.scel文件转换为.txt文件,详细解析了.scel文件的结构,并提供了转换过程中的关键代码和参考资料。
2341

被折叠的 条评论
为什么被折叠?



