#环境需求 Python2
1 #!/bin/python
2 # -*- coding: utf-8 -*-
3
4
5 import struct
6 import sys
7 import binascii
8 import pdb
9
10 try:
11 reload(sys)
12 sys.setdefaultencoding('utf-8')
13 except:
14 pass
15
16 # 搜狗的scel词库就是保存的文本的unicode编码,每两个字节一个字符(中文汉字或者英文字母)
17 # 找出其每部分的偏移位置即可
18 # 主要两部分
19 # 1.全局拼音表,貌似是所有的拼音组合,字典序
20 # 格式为(index,len,pinyin)的列表
21 # index: 两个字节的整数 代表这个拼音的索引
22 # len: 两个字节的整数 拼音的字节长度
23 # pinyin: 当前的拼音,每个字符两个字节,总长len
24 #
25 # 2.汉语词组表
26 # 格式为(same,py_table_len,py_table,{word_len,word,ext_len,ext})的一个列表
27 # same: 两个字节 整数 同音词数量
28 # py_table_len: 两个字节 整数
29 # py_table: 整数列表,每个整数两个字节,每个整数代表一个拼音的索引
30 #
31 # word_len:两个字节 整数 代表中文词组字节数长度
32 # word: 中文词组,每个中文汉字两个字节,总长度word_len
33 # ext_len: 两个字节 整数 代表扩展信息的长度,好像都是10
34 # ext: 扩展信息 前两个字节是一个整数(不知道是不是词频) 后八个字节全是0
35 #
36 # {word_len,word,ext_len,ext} 一共重复same次 同音词 相同拼音表
37
38 # 拼音表偏移,
39 startPy = 0x1540;
40
41 # 汉语词组表偏移
42 startChinese = 0x2628;
43
44 # 全局拼音表
45
46 GPy_Table = {}
47
48 # 解析结果
49 # 元组(词频,拼音,中文词组)的列表
50 GTable = []
51
52
53 def byte2str(data):
54 '''''将原始字节码转为字符串'''
55 i = 0;
56 length = len(data)
57 ret = u''
58 while i < length:
59 x = data[i] + data[i + 1]
60 t = unichr(struct.unpack('H', x)[0])
61 if t == u'\r':
62 ret += u'\n'
63 elif t != u' ':
64 ret += t
65 i += 2
66 return ret
67
68
69 # 获取拼音表
70 def getPyTable(data):
71 if data[0:4] != "\x9D\x01\x00\x00":
72 return None
73 data = data[4:]
74 pos = 0
75 length = len(data)
76 while pos < length:
77 index = struct.unpack('H', data[pos] + data[pos + 1])[0]
78 # print index,
79 pos += 2
80 l = struct.unpack('H', data[pos] + data[pos + 1])[0]
81 # print l,
82 pos += 2
83 py = byte2str(data[pos:pos + l])
84 # print py
85 GPy_Table[index] = py
86 pos += l
87
88 # 获取一个词组的拼音
89
90
91 def getWordPy(data):
92 pos = 0
93 length = len(data)
94 ret = u''
95 while pos < length:
96 index = struct.unpack('H', data[pos] + data[pos + 1])[0]
97 ret += GPy_Table[index]
98 pos += 2
99 return ret
100
101
102 # 获取一个词组
103 def getWord(data):
104 pos = 0
105 length = len(data)
106 ret = u''
107 while pos < length:
108 index = struct.unpack('H', data[pos] + data[pos + 1])[0]
109 ret += GPy_Table[index]
110 pos += 2
111 return ret
112
113
114 # 读取中文表
115 def getChinese(data):
116 # import pdb
117 # pdb.set_trace()
118
119 pos = 0
120 length = len(data)
121 while pos < length:
122 # 同音词数量
123 same = struct.unpack('H', data[pos] + data[pos + 1])[0]
124 # print '[same]:',same,
125
126 # 拼音索引表长度
127 pos += 2
128 py_table_len = struct.unpack('H', data[pos] + data[pos + 1])[0]
129 # 拼音索引表
130 pos += 2
131 py = getWordPy(data[pos: pos + py_table_len])
132
133 # 中文词组
134 pos += py_table_len
135 for i in xrange(same):
136 # 中文词组长度
137 c_len = struct.unpack('H', data[pos] + data[pos + 1])[0]
138 # 中文词组
139 pos += 2
140 word = byte2str(data[pos: pos + c_len])
141 # 扩展数据长度
142 pos += c_len
143 ext_len = struct.unpack('H', data[pos] + data[pos + 1])[0]
144 # 词频
145 pos += 2
146 count = struct.unpack('H', data[pos] + data[pos + 1])[0]
147
148 # 保存
149 GTable.append((count, py, word))
150
151 # 到下个词的偏移位置
152 pos += ext_len
153
154
155 def deal(file_name):
156 print '-' * 60
157 f = open(file_name, 'rb')
158 data = f.read()
159 f.close()
160
161 if data[0:12] != "\x40\x15\x00\x00\x44\x43\x53\x01\x01\x00\x00\x00":
162 print "确认你选择的是搜狗(.scel)词库?"
163 sys.exit(0)
164 # pdb.set_trace()
165
166 print "词库名:", byte2str(data[0x130:0x338]) # .encode('GB18030')
167 print "词库类型:", byte2str(data[0x338:0x540]) # .encode('GB18030')
168 print "描述信息:", byte2str(data[0x540:0xd40]) # .encode('GB18030')
169 print "词库示例:", byte2str(data[0xd40:startPy]) # .encode('GB18030')
170
171 getPyTable(data[startPy:startChinese])
172 getChinese(data[startChinese:])
173
174
175 if __name__ == '__main__':
176
177 # 将要转换的词库添加在这里就可以了
178 #o = [u'明星【官方推荐】.scel',]C:\Users\samsung\Desktop\文本分类资料\生活\理财_65\博彩类_7彩票词汇大全.scel
179 o =[u"北方民族大学.scel"]
180
181 for f in o:
182 deal(f)
183
184 # 保存结果
185 f = open('8.txt', 'w')
186 for word in GTable:
187 # GTable保存着结果,是一个列表,每个元素是一个元组(词频,拼音,中文词组),有需要的话可以保存成自己需要个格式
188 # 我没排序,所以结果是按照上面输入文件的顺序
189 #f.write(unicode(word).encode('GB18030')) # 最终保存文件的编码,可以自给改
190 f.write(word[2])
191 f.write('\n')
192 f.close()