汉字首字母提取研究

写在最前面

此贴纯属记录今天的探索过程,在实际中,为解决问题可能会采用手动生成(如人数少),或VBA代码加手动修改等方法,而不会这样无聊去研究一天。我也把主要的代码以及最后得到的数据,共享给大家,可直接下载使用。

链接: https://pan.baidu.com/s/1896YPdDgRdGcSsVTeYKy_Q?pwd=eyc6 提取码: eyc6

因此,纯属探讨,欢迎高手批评指教。

一、需求的提出

在做点菜系统、学生管理系统等需要快速查询的功能时,常会将汉字的首字母提取出来,作为模糊查询时使用。例如,查询“张三”时,用“ZS”肯定比输入汉字快捷,还避免了同音字的问题。

二、网上的解决办法

  1. VBA编程的方法

网上比较好找,大概的代码如下:(VBA代码,好像CSDN不支持)

Function pinyin(p As String) As String
    i = Asc(p)
    Select Case i
        Case -20319 To -20284: pinyin = "A"
        Case -20283 To -19776: pinyin = "B"
        Case -19775 To -19219: pinyin = "C"
        Case -19218 To -18711: pinyin = "D"
        Case -18710 To -18527: pinyin = "E"
        Case -18526 To -18240: pinyin = "F"
        Case -18239 To -17923: pinyin = "G"
        Case -17922 To -17418: pinyin = "H"
        Case -17417 To -16475: pinyin = "J"
        Case -16474 To -16213: pinyin = "K"
        Case -16212 To -15641: pinyin = "L"
        Case -15640 To -15166: pinyin = "M"
        Case -15165 To -14923: pinyin = "N"
        Case -14922 To -14915: pinyin = "O"
        Case -14914 To -14631: pinyin = "P"
        Case -14630 To -14150: pinyin = "Q"
        Case -14149 To -14091: pinyin = "R"
        Case -14090 To -13319: pinyin = "S"
        Case -13318 To -12839: pinyin = "T"
        Case -12838 To -12557: pinyin = "W"
        Case -12556 To -11848: pinyin = "X"
        Case -11847 To -11056: pinyin = "Y"
        Case -11055 To -2050: pinyin = "Z"
        Case Else: pinyin = p
    End Select
End Function
Function getFirstLetter(str)
    For i = 1 To Len(str)
        getFirstLetter = getFirstLetter & pinyin(Mid(str, i, 1))
    Next i
End Function

参考网址:https://www.cnblogs.com/flyingfishing/p/12925577.html

存在的问题是:很多汉字不准确,例如:以下的字都返回的字母“Z”。

  1. 通过word的拼音指南来提取

即先在word自动生成拼音,再复制到excel中,通过phonetic函数进行提取。不但能获得首字母,还能获得带声调的拼音。

参考网址:利用Excel+Word巧妙提取汉字拼音 - 简书 (jianshu.com)

三、我的解决办法

  1. 下载一份常用汉字。文件 (lanzoui.com)。并把这份汉字去掉回车、去掉空格,存在hanzi.txt中。

  1. 通过python爬虫抓取百度汉语上的拼音。

import json
import traceback

import requests
import re
cnt = 0
cnt_e = 0
dic = dict()
with open("hanzi.txt", "r", encoding='utf-8') as f:  # 打开文件
    words = f.read()  # 读取文件
for word in words:
    cnt += 1
    print(cnt, ",", word)
    # 设置URL
    url = "https://dict.baidu.com/s?wd={}&ptype=zici".format(word)
    response = requests.get(url)
    response.encoding = 'utf-8'
    page_text = response.text
    # 空字符处理。
    page_text = page_text.replace(chr(8194), '')
    page_text = page_text.replace(chr(10), '')
    page_text = page_text.replace(chr(32), '')
    page_text = page_text.replace(chr(13), '\n')
    # 用正则找出拼音来
    reg = re.compile(r'<divclass="pronounce"id="pinyin"><span>(\S*</b>)<aherf')
    tmp = ''
    try:  # 有个别字返回的格式不一样,需要单独处理。 
        tmp = reg.findall(page_text)[0]
    except Exception as e:
        traceback.print_exc()
        cnt_e += 1
    reg = re.compile(r'<b>(\w*)</b>')
    lst = reg.findall(tmp)
    tmp = ",".join(lst)
    dic[word] = tmp
with open('dic.txt', 'w', encoding='utf-8') as f:
    # 将dic dumps json 格式进行写入
    f.write(json.dumps(dic, ensure_ascii=False))
  1. 整理抓取到的数据。把带音调的字母,替换成普通的字母。

抓取的结果:

  1. 去除查不到的字

import json
with open('dic.txt', 'r', encoding='utf-8') as f:
    tmp = f.read()
dic = eval(tmp)
with open('没查到的汉字.txt', 'r', encoding='utf-8') as f:
    words = f.read()
for word in words:
    del dic[word]
with open('dic_exist.txt', 'w', encoding='utf-8') as f:
    f.write(json.dumps(dic, ensure_ascii=False))
  1. 清洗好后的数据,存到数据表。

  1. 把带声调的字母,换成普通字母。

  1. 提取首字母。

  1. 去掉同样的,比如“干”一声和“干”四声,声母是相同的。用集合。

  1. 输出到txt 时,采用tab分隔。

import re
with open('dic_exist.txt', 'r', encoding='utf-8') as f:
    tmp = f.read()
dic = eval(tmp)
lst = []
for key in dic:
    lst.append('{}\t{}'.format(key, dic[key]))  # 字和拼音中间用tab分隔,便于复制到excel。
tmp = '\n'.join(lst)  # 两个字之间用回车分隔,便于复制到excel中。
# 把结果写入dic_with_tone.txt
with open('dic_with_tone.txt', 'w', encoding='utf-8') as f:
    f.write(tmp)
# 以下用正则把声调去掉
dic_rep = {'ā|á|ǎ|à': 'a', 'ō|ó|ǒ|ò': 'o', 'ē|é|ě|è': 'e', 'ī|í|ǐ|ì': 'i', 'ū|ú|ǔ|ù': 'u', 'ǘ|ǚ|ǜ': 'v'}
for key in dic_rep:
    reg = re.compile(key)
    tmp = reg.sub(dic_rep[key], tmp)
# 把结果写入dic_no_tone.txt
with open('dic_no_tone.txt', 'w', encoding='utf-8') as f:
    f.write(tmp)
# 再把首字母找出来,去掉同样的,比如“干”一声和“干”四声,声母是相同的。
lst_return = []
lst = tmp.split('\n')
set_first_letter = set()
for line in lst:
    # line 代表去掉声调后的每一行
    [word, pinyin] = line.split('\t')
    yinjies = pinyin.split(',')  # 把拼音按逗号分成若干音节,结果是列表
    for yinjie in yinjies:
        set_first_letter.add(yinjie[0].upper())
    lst_return.append('{}\t{}'.format(word, ','.join(set_first_letter)))  # 用集合去重
    set_first_letter.clear()
with open('dic_first_letter.txt', 'w', encoding='utf-8') as f:
    f.write('\n'.join(lst_return))

你可以想你不到,“丁”和“厂”都是多音字:

丁dīng,zhēng

厂chǎng,ān

  1. 由于我的应用场景很简单,暂时就存在excel表格中,通过vlookup函数进行查询。最后成功了7894个。

四、多音字探讨

例如,“茜”,xi,qian。比如一个员工叫“张茜”,首字母可能是“ZX”或者“ZQ”。

在生成名字首字母时,可以两个都生成,即“ZQ,ZX”,这样在模糊查询时,就可以解决多音字的问题。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MFC是Microsoft Foundation Class库的简称,它是用于开发Windows桌面应用程序的一个C++类库。在MFC中提取汉字首字母可以通过以下步骤实现: 1. 将汉字字符串转换为Unicode编码:先将字符串转换为宽字符型CString类型对象,然后使用WideCharToMultiByte函数将其转换为Unicode编码。 2. 提取汉字首字母:遍历汉字字符串的每个字符,对于每个汉字字符,判断其Unicode编码是否在汉字范围内(0x4E00-0x9FA5)。 3. 对于汉字字符,利用其Unicode编码计算出首字母的索引:首先减去0x4E00(或转换为十进制得19968),然后除以94将其余数与0x41(十进制为65)相加。 4. 将首字母索引转换为对应的字符:加上0x41得到的索引即为首字母的ASCII码,使用对应的ASCII码转换为字符,即可得到首字母。 5. 将提取首字母存储起来:可以使用一个字符型变量或字符串对象,依次将每个汉字首字母拼接起来。 需要注意的是,在提取汉字首字母时,还需要考虑到多音字的情况,因为一个汉字可能对应多个不同的音节。一种常用的方法是使用拼音库,将汉字转换为拼音,然后提取拼音的首字母作为汉字首字母。 以上是一种基于汉字Unicode编码的提取首字母的方法,在实际应用中,还可以使用其他的提取规则,如使用拼音库或其他语言处理库来实现。总之,根据具体需求选择合适的方法,可以实现汉字首字母提取

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值