>웹 프론트엔드 >JS 튜토리얼 >JS 병음 입력 방법에 대한 자세한 소개와 함께 JavaScript에서 한자를 병음으로 변환하는 궁극적인 솔루션

JS 병음 입력 방법에 대한 자세한 소개와 함께 JavaScript에서 한자를 병음으로 변환하는 궁극적인 솔루션

黄舟
黄舟원래의
2017-03-03 15:22:232341검색

서문

JS를 이용한 한자와 병음 변환에 대한 글이 인터넷에 많이 떠돌고 있는데 꽤 지저분하고 다 복사되어 있고, 그렇지 않은 경우도 있습니다. 다성 문자를 지원하고 일부는 성조를 지원하지 않으며 일부 사전 파일이 너무 큽니다. 예를 들어 때로는 중국어 병음의 첫 글자만 가져와야 하는데 200kb 사전 파일을 가져와야 하는데 이는 실제 요구 사항을 충족할 수 없습니다. .

결산하자면, 인터넷에서 흔히 볼 수 있는 여러 사전 파일을 세심하게 정리하고 수정했으며, 간단하게 바로 사용할 수 있는 도구 라이브러리를 캡슐화했습니다.

코드 및 DEMO 데모

github 프로젝트 주소: https://github.com/liuxianan/pinyinjs

전체 데모 데모: http://demo.liuxianan.com /pinyinjs/

한자를 병음으로 변환:

병음을 한자로 변환:

한자 및 병음 관련 지식의 대중화

한자 범위

일반적으로 유니코드 인코딩에서 한자의 범위는 /^[u2E80-u9FFF]+$/(11904-40959)라고 생각되지만, 본 글에 사용된 여러 사전 파일의 한자 범위는 모두 /^[u4E00-u9FA5]+$/, 즉 (19968-40869) 인데, 그 한자가 별도로 존재한다. 유니코드 위치는 12295입니다.

병음 조합

한자의 초성은 21개입니다: b, p, m, f, d, t, n, l, g, k, h, j, q, x, zh , ch, sh, r, z, c, s, 6개의 단일 결승전(a, o, e, i, u, v) 및 18개의 복합 결승전(ai, ei, ui, ao, ou , iu )을 포함하여 24개의 결승전, 즉, ve, er, an , en , in, un , vn , ang, eng, ing , ong, 초성과 종성이 쌍으로 결합된다고 가정하면, 실제 상황은 24X21=504가 될 것입니다. 조합은 bv, gie, ve 등과 같이 의미 없는 조합입니다. 이 부분을 제거해도 여전히 412가지 유형이 남아 있습니다.

병음사전 파일

사전 파일 크기에 따라 오름차순으로 소개됩니다.

사전 1: 병음 첫 글자

이 사전 파일의 내용은 대략 다음과 같습니다.

/**
 * 拼音首字母字典文件
 */
var pinyin_dict_firstletter = {};
pinyin_dict_firstletter.all = "YDYQSXMWZSSXJBYMGCCZQPSSQBYCDSCDQLDYLYBSSJG...";
pinyin_dict_firstletter.polyphone = {"19969":"DZ","19975":"WM","19988":"QJ","20048":"YL",...};

이 데이터 사전은 유니코드 문자를 4E00(19968)-으로 변환합니다. 9FA5 (40869) 총 20,902개의 한자 병음 이니셜을 이어붙여 매우 긴 문자열을 얻은 후, 다성 문자가 포함된 한자(총 370 다성 문자)를 별도로 나열합니다. 사전 파일 크기는 25kb입니다.

이 사전 파일의 장점은 크기가 작고 다중 음성 문자를 지원한다는 것입니다. 단점은 병음의 첫 글자만 얻을 수 있다는 것입니다.

사전 2: 자주 사용되는 한자

본 사전 파일은 한자를 병음에 따라 분류한 것으로, 총 401개의 조합과 6763개의 상용 한자를 지원하지 않습니다. 인터넷에서 수집한 것이고 포함된 단어 수가 적기 때문에 파일 크기는 24kb에 불과합니다. 시간이 나면 확장할 수 있는지 살펴보겠습니다.

사전 파일의 대략적인 내용은 다음과 같습니다(예시일 뿐이라 일부만 표시됩니다):

/**
 * 常规拼音数据字典,收录常见汉字6763个,不支持多音字
 */
var pinyin_dict_notone = 
{
    "a":"啊阿锕",
    "ai":"埃挨哎唉哀皑癌蔼矮艾碍爱隘诶捱嗳嗌嫒瑷暧砹锿霭",
    "an":"鞍氨安俺按暗岸胺案谙埯揞犴庵桉铵鹌顸黯",
    "ang":"肮昂盎",
    "ao":"凹敖熬翱袄傲奥懊澳坳拗嗷噢岙廒遨媪骜聱螯鏊鳌鏖",
    "ba":"芭捌扒叭吧笆八疤巴拔跋靶把耙坝霸罢爸茇菝萆捭岜灞杷钯粑鲅魃",
    "bai":"白柏百摆佰败拜稗薜掰鞴",
    "ban":"斑班搬扳般颁板版扮拌伴瓣半办绊阪坂豳钣瘢癍舨",
    "bang":"邦帮梆榜膀绑棒磅蚌镑傍谤蒡螃",
    "bao":"苞胞包褒雹保堡饱宝抱报暴豹鲍爆勹葆宀孢煲鸨褓趵龅",
    "bo":"剥薄玻菠播拨钵波博勃搏铂箔伯帛舶脖膊渤泊驳亳蕃啵饽檗擘礴钹鹁簸跛",
    "bei":"杯碑悲卑北辈背贝钡倍狈备惫焙被孛陂邶埤蓓呗怫悖碚鹎褙鐾",
    "ben":"奔苯本笨畚坌锛"
    // 省略其它
};

나중에 오류가 많다는 것을 차츰 알게 되었습니다. 이 사전 파일은 의 병음과 같이 nue(정확한 표기는 nve여야 함)로 썼고, thang로 썼고, 다성 문자는 지원하지 않아서 나중에 다시 생성했습니다. 다른 사전 파일을 기반으로 한 이 형식의 사전 파일:

  • 총 404개의 병음 조합

  • 일반적으로 사용되는 6763개의 한자 포함

  • 다음성 문자 지원

  • 성조 지원 안함

  • 파일 크기 27kb

동시에 온라인에서 흔히 사용하는 6763자를 기준으로 한자 사용 빈도표는 이 6763자를 사용 빈도에 따라 정렬하여 만족스러운 JS 버전의 입력 방법을 제공합니다. 실현될 수 있습니다.

그리고 또 다른 완전한 사전 파일에 따르면 실제로 412개의 병음 조합이 있는 것으로 밝혀졌습니다. 위 사전 파일에 나타나지 않는 8개의 발음은

chua,den,eng,fiao,m,kei,nun,shei

사전입니다. 3: 궁극의 사전

우선 인터넷에서 다음과 같은 구조의 사전 파일(이하 사전 A라 함)을 찾았는데, 구체적인 성조와 다성어를 지원하는지 기억이 나지 않습니다. 유니코드 문자를 4E00(19968)-9FA5(40869)으로 변환합니다. 총 20902개의 한자(〇가 포함된 경우 20903)가 병음으로 나열됩니다. 사전 파일 크기는 280kb:

3007 (ling2)
4E00 (yi1)
4E01 (ding1,zheng1)
4E02 (kao3)
4E03 (qi1)
4E04 (shang4,shang3)
4E05 (xia4)
4E06 (none0)
4E07 (wan4,mo4)
4E08 (zhang4)
4E09 (san1)
4E0A (shang4,shang3)
4E0B (xia4)
4E0C (ji1)
4E0D (bu4,bu2,fou3)
4E0E (yu3,yu4,yu2)
4E0F (mian3)
4E10 (gai4)
4E11 (chou3)
4E12 (chou3)
4E13 (zhuan1)
4E14 (qie3,ju1)
...
그 중 발음이 없거나,

로 일률적으로 표시된 한자의 경우, 총 525개의 한자가 있다고 계산했습니다. none0

사전 파일의 크기를 최대한 줄여보자는 목표에 맞춰 위 파일의 첫 번째 〇(3007)을 제외하면 나머지는 모두 연속인 것을 발견하여 다음과 같이 변경했습니다. 다음 구조에서는 파일 크기도

에서 280kb로 줄었습니다. 117kb

var pinyin_dict_withtone = "yi1,ding1 zheng1,kao3,qi1,shang4 shang3,xia4,none0,wan4 mo4,zhang4,san1,shang4 shang3,xia4,ji1,
bu4 bu2 fou3,yu3 yu4 yu2,mian3,gai4,chou3,chou3,zhuan1,qie3 ju1...";

이 사전 파일의 단점은 , 필요합니다. 알고리즘은 적절하게 배치된 문자를

로 변환합니다. xiǎo míng tóng xué

本来还准备自己尝试写一个转换的方法的,后来又找到了如下字典文件(下面称为字典B),它收录了20867个汉字,也支持声调和多音字,但是声调是直接标在字母上方的,由于它将汉字也列举出来,所以文件体积比较大,有327kb,大致内容如下:

{
    "吖": "yā,ā",
    "阿": "ā,ē",
    "呵": "hē,a,kē",
    "嗄": "shà,á",
    "啊": "ā,á,ǎ,à,a",
    "腌": "ā,yān",
    "锕": "ā",
    "錒": "ā",
    "矮": "ǎi",
    "爱": "ài",
    "挨": "āi,ái",
    "哎": "āi",
    "碍": "ài",
    "癌": "ái",
    "艾": "ài",
    "唉": "āi,ài",
    "蔼": "ǎi"
    /* 省略其它 */
}

但是经过比对,发现有502个汉字是字典A中读音为none但是字典B中有读音的,还有21个汉字是字典A中有但是B中没有的:

{
    "兙": "shí kè",
    "兛": "qiān",
    "兝": "fēn",
    "兞": "máo",
    "兡": "bǎi kè",
    "兣": "lǐ",
    "唞": "dǒu",
    "嗧": "jiā lún",
    "囍": "xǐ",
    "堎": "lèng líng",
    "猤": "hú",
    "瓩": "qián wǎ",
    "礽": "réng",
    "膶": "rùn",
    "芿": "rèng",
    "蟘": "tè",
    "貣": "tè",
    "酿": "niàng niàn niáng",
    "醸": "niàng",
    "鋱": "tè",
    "铽": "tè"
}

还有7个汉字是B中有但是A中没有的:

{
    "㘄": "lēng",
    "䉄": "léng",
    "䬋": "léng",
    "䮚": "lèng",
    "䚏": "lèng,lì,lìn",
    "㭁": "réng",
    "䖆": "niàng"
}

所以我在字典A的基础上将二者进行了合并,得到了最终的字典文件pinyin_dict_withtone.js,文件大小为122kb

var pinyin_dict_withtone = "yī,dīng zhēng,kǎo qiǎo yú,qī,shàng,xià,hǎn,wàn mò,zhàng,sān,shàng shǎng,xià,qí jī...";

如何使用

我将这几种字典文件放在一起并简单封装了一下解析方法,使用中可以根据实际需要引入不同字典文件。

封装好的3个方法:

/**
 * 获取汉字的拼音首字母
 * @param str 汉字字符串,如果遇到非汉字则原样返回
 * @param polyphone 是否支持多音字,默认false,如果为true,会返回所有可能的组合数组
 */
pinyinUtil.getFirstLetter(str, polyphone);
/**
 * 根据汉字获取拼音,如果不是汉字直接返回原字符
 * @param str 要转换的汉字
 * @param splitter 分隔字符,默认用空格分隔
 * @param withtone 返回结果是否包含声调,默认是
 * @param polyphone 是否支持多音字,默认否
*/
pinyinUtil.getPinyin(str, splitter, withtone, polyphone);
/**
 * 拼音转汉字,只支持单个汉字,返回所有匹配的汉字组合
 * @param pinyin 单个汉字的拼音,不能包含声调
 */
pinyinUtil.getHanzi(pinyin);

下面分别针对不同场合如何使用作介绍。

如果你只需要获取拼音首字母

<script type="text/javascript" src="pinyin_dict_firstletter.js"></script>
<script type="text/javascript" src="pinyinUtil.js"></script>

<script type="text/javascript">
pinyinUtil.getFirstLetter(&#39;小茗同学&#39;); // 输出 XMTX
pinyinUtil.getFirstLetter(&#39;大中国&#39;, true); // 输出 [&#39;DZG&#39;, &#39;TZG&#39;]
</script>

需要特别说明的是,如果你引入的是其它2个字典文件,也同样可以获取拼音首字母的,只是说用这个字典文件更适合。

如果拼音不需要声调

<script type="text/javascript" src="pinyin_dict_noletter.js"></script>
<script type="text/javascript" src="pinyinUtil.js"></script>

<script type="text/javascript">
pinyinUtil.getPinyin(&#39;小茗同学&#39;); // 输出 &#39;xiao ming tong xue&#39;
pinyinUtil.getHanzi(&#39;ming&#39;); // 输出 &#39;明名命鸣铭冥茗溟酩瞑螟暝&#39;
</script>

如果需要声调或者需要处理生僻字

<script type="text/javascript" src="pinyin_dict_withletter.js"></script>
<script type="text/javascript" src="pinyinUtil.js"></script>

<script type="text/javascript">
pinyinUtil.getPinyin(&#39;小茗同学&#39;); // 输出 &#39;xiǎo míng tóng xué&#39;
pinyinUtil.getPinyin(&#39;小茗同学&#39;, &#39;-&#39;, true, true); // 输出 [&#39;xiǎo-míng-tóng-xué&#39;, &#39;xiǎo-míng-tòng-xué&#39;]
</script>

关于简单拼音输入法

一个正式的输入法需要考虑的东西太多太多,比如词库、用户个人输入习惯等,这里只是实现一个最简单的输入法,没有任何词库(虽然加上也可以,但是web环境不适合引入太大的文件)。

推荐使用第二个字典文件pinyin_dict_noletter.js,虽然字典三字数更多,但是不能按照汉字使用频率排序,一些生僻字反而在前面。

<link rel="stylesheet" type="text/css" href="simple-input-method/simple-input-method.css">
<input type="text" class="test-input-method"/>
<script type="text/javascript" src="pinyin_dict_noletter.js"></script>
<script type="text/javascript" src="pinyinUtil.js"></script>
<script type="text/javascript" src="simple-input-method/simple-input-method.js"></script>
<script type="text/javascript">
    SimpleInputMethod.init(&#39;.test-input-method&#39;);
</script>

结语

由于本工具类的目标环境是web,而web注定了文件体积不能太大,所以不能引入太大的词库文件,由于没有词库的支持,所以多音字无法识别,实现的拼音输入法也无法智能地匹配出合适的词语,需要词库支持的可以参考这个nodejs环境下的项目:http://www.php.cn/

 以上就是JavaScript 汉字与拼音互转终极方案 附JS拼音输入法的详细介绍的内容,更多相关内容请关注PHP中文网(www.php.cn)!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.