当前位置:AIGC资讯 > 数据采集 > 正文

PHP高性能输出UNICODE正则汉字列表 汉字转拼音多音字解决方案 搜索引擎分词细胞词库更新 搜狗词库提取TXT

目前现状

汉字转拼音

难度大就大在 多音字!行业上较准确的是基于词语、成语的识别。搜狗有1万多词库 每个词库又很大:
比如:

了 我们读 le 但是成语 一了百了 中 读 liao 解元 作为姓名 应该读 xie yuan 我是解元的家人解决了1个问题  作为一句话 无法切割哪个是人名的读法 哪个是普通读法

最终 无法达到100%精确 只能尽可能准确 加大正确率!

防止采集

HookPHP项目地址:https://github.com/letwang/HookPHP,如果大家喜欢的话,请给个Star,让更多的人看到优秀的开源项目,为PHP发展贡献一把力量!QQ架构探讨群:679116380

搜索引擎

分词同理:

你无法预料明天的互联网会出现哪些新词而导致你必须重新分词才能搜到新词。

每年高考汉语都有修正版 现在一次站在巨人肩膀上固定好词库 以后还是要根据高考方案来更新?所以 最终 无法达到100%精确 只能尽可能准确 加大正确率!

解决方案

1.运用采集工具批量采集搜狗词库到本地

2.执行Python程序,把上述词库提取出到TXT文档中

#!/usr/bin/python
# -*- coding: utf-8 -*-
#https://my.oschina.net/cart
#letwang

import struct,sys,binascii,pdb,os

startPy = 0x1540;
startChinese = 0x2628;

GPy_Table ={}
GTable = []

def byte2str(data):
    i = 0;
    length = len(data)
    ret = u''
    while i < length:
        x = data[i] + data[i+1]
        t = unichr(struct.unpack('H',x)[0])
        if t == u'\r':
            ret += u'\n'
        elif t != u' ':
            ret += t
        i += 2
    return ret

def getPyTable(data):

    if data[0:4] != "\x9D\x01\x00\x00":
        return None
    data = data[4:]
    pos = 0
    length = len(data)
    while pos < length:
        index = struct.unpack('H',data[pos]+data[pos+1])[0]
        pos += 2
        l = struct.unpack('H',data[pos]+data[pos+1])[0]
        pos += 2
        py = byte2str(data[pos:pos+l])
        GPy_Table[index]=py
        pos += l

def getWordPy(data):
    pos = 0
    length = len(data)
    ret = u''
    while pos < length:
        index = struct.unpack('H',data[pos]+data[pos+1])[0]
        ret += GPy_Table[index]
        pos += 2    
    return ret

def getWord(data):
    pos = 0
    length = len(data)
    ret = u''
    while pos < length:
        index = struct.unpack('H',data[pos]+data[pos+1])[0]
        ret += GPy_Table[index]
        pos += 2    
    return ret

def getChinese(data):    
    pos = 0
    length = len(data)
    while pos < length:
        same = struct.unpack('H',data[pos]+data[pos+1])[0]

        pos += 2
        py_table_len = struct.unpack('H',data[pos]+data[pos+1])[0]
        pos += 2
        py = getWordPy(data[pos: pos+py_table_len])

        pos += py_table_len
        for i in xrange(same):
            c_len = struct.unpack('H',data[pos]+data[pos+1])[0]
            pos += 2  
            word = byte2str(data[pos: pos + c_len])
            pos += c_len        
            ext_len = struct.unpack('H',data[pos]+data[pos+1])[0]
            pos += 2
            count  = struct.unpack('H',data[pos]+data[pos+1])[0]
            GTable.append((count,py,word))
            pos +=  ext_len

def deal(file_name):
    print '-'*60
    f = open(file_name,'rb')
    data = f.read()
    f.close()

    if data[0:12] !="\x40\x15\x00\x00\x44\x43\x53\x01\x01\x00\x00\x00":
        print "确认你选择的是搜狗(.scel)词库?"
        sys.exit(0)

    print "词库名:" ,byte2str(data[0x130:0x338])
    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__':
    o = [fname for fname in os.listdir("./") if fname[-5:] == ".scel"]
    for f in o:
        deal(f)
    f = open('sougou.txt','w')
    for count,py,word in GTable:
        f.write( unicode('{%(count)s}' %{'count':count}+py+' '+ word).encode('utf-8') )
        f.write('\n')
    f.close()

把上述保存为文件名sougou,且所有采集好的搜狗词库放置与其同级,执行 python sougou,会生成sougou.txt,里面就是成千上万的 词频、拼音、分词,再使用Cron定时任务采集、更新词库即可保持汉字转拼音、搜索引擎分词元数据常新。

实际,除了搜狗还有其他输入法词库可供类似操作,最终目的是词库够新 够全!

另外,在unicode官网可以查到中文汉字通用的unicode编码范围。

PHP高性能输出UNICODE正则汉字列表

网上,针对汉字、特殊字符的UNICODE 编码、解码实现,方法诸多,但是大多是复制粘贴,没有新意!以下为原创:

<?php
for ($i = 0x4e00; $i <= 0x9fa5; $i ++) {
    echo json_decode('"\u' . dechex($i) . '"');
}

上述会打印20902个汉字列表,这也解释了上述正则是如何透明的工作匹配汉字的,其中有几个知识点:

16进制以0x开头 16进制范围 0-9 a-f 不区分大小写 16进制可以巧妙的通过递增进行十进制默认转换 10进制转换为16进制方法是dechex \u 加上 1个16进制字符 就是1个字符的UNICODE形式 json_decode 加上 带双引号的UNICODE字符 可以轻易转换为常用识别字符

PHP UNICODE 汉字 编码:

var_dump(json_encode('2018 ABC 我是中国人!网站:http://my.oschina.net/cart/'));

上述就实现了PHP中对汉字、特殊字符的 UNICODE 编码,会输出:

string(96) ""2018 ABC \u6211\u662f\u4e2d\u56fd\u4eba\uff01\u7f51\u7ad9\uff1ahttp:\/\/my.oschina.net\/cart\/""

PHP UNICODE 汉字 解码:

如果我们尝试

var_dump(json_decode('2018 ABC \u6211\u662f\u4e2d\u56fd\u4eba\uff01\u7f51\u7ad9\uff1ahttp:\/\/my.oschina.net\/cart\/'));

或者

var_dump(json_decode("2018 ABC \u6211\u662f\u4e2d\u56fd\u4eba\uff01\u7f51\u7ad9\uff1ahttp:\/\/my.oschina.net\/cart\/"));

结果都是

NULL

是错误的,并没有按照我们的意愿解码!

因为你并没有传入正确的json格式字符串!!!

心细的同学肯定已经发现,上述json_encode输出的是

"2018 ABC \u6211\u662f\u4e2d\u56fd\u4eba\uff01\u7f51\u7ad9\uff1ahttp:\/\/my.oschina.net\/cart\/"

注意输出字符串两段的 双引号, 这也是输出 json_encode 内容的一部分!很重要!

所以我们如果想正确的用json_decode解码,我们以下操作即可:

var_dump(json_decode('"2018 ABC \u6211\u662f\u4e2d\u56fd\u4eba\uff01\u7f51\u7ad9\uff1ahttp:\/\/my.oschina.net\/cart\/"'));

正确的解码输出了我们的结果:

string(63) "2018 ABC 我是中国人!网站:http://my.oschina.net/cart/"

看看,没有什么技术含量,都是基本知识的掌握!

PHP UNICODE 汉字 不规则形式 解码:

也许有的同学没有那么幸运,得到的字符串形如:

2018 ABC u6211u662fu4e2du56fdu4ebauff01u7f51u7ad9uff1ahttp:\/\/my.oschina.net\/cart\/

怎么解码?心细的同事已经发现,所有的u少了\,应该是\u,u后面跟随的是【0-9a-f】4位字符串!

潇洒破之(preg_replace的e修饰符在PHP新版本已经弃用了,所以官方推荐使用preg_replace_callback代替之!):

$str = '2018 ABC u6211u662fu4e2du56fdu4ebauff01u7f51u7ad9uff1ahttp:\/\/my.oschina.net\/cart\/';
var_dump(json_decode('"'.preg_replace_callback("/u([0-9a-f]{4})/", function($match){return '\u'.$match[1];}, $str).'"'));

就1句话,完工,下班。

更新时间 2023-11-08