需求
此前項目中有一個中文轉(zhuǎn)拼音的需求,于是整理了一下實現(xiàn)方法寇荧。
在轉(zhuǎn)換過程中执隧,這里我保留了數(shù)字和字母,其他特殊字符或者空格將會被去掉捅膘。如
測試
會被轉(zhuǎn)換成CeShi
滚粟。(可自行修改convert2Pinyin()
方法實現(xiàn)其他需求)
實現(xiàn)
話不多說(Github Demo)
<!-- html -->
<input id="input" value="測試" />
<input id="output" disabled />
// js
window.onload = () => {
const input = document.getElementById('input')
const output = document.getElementById('output')
// 失焦進(jìn)行轉(zhuǎn)換
input.addEventListener('blur', () => {
const val = input.value
output.value = convertToPinyin(val)
})
/**
* 轉(zhuǎn)換成拼音(若有空格凡壤、特殊字符將被移除)
*
* @param {string} sourceStr 原始數(shù)據(jù)
*/
const convertToPinyin = sourceStr => {
// 目標(biāo)數(shù)據(jù)
let targetStr = ''
// 匹配中文
const cnReg = /[\u4e00-\u9fa5]/
// 匹配數(shù)字和英文
const enReg = /[a-zA-Z0-9]/
// 保留英文和數(shù)字
const keep = true
// 遍歷源數(shù)據(jù)
for (let i = 0, len = sourceStr.length; i < len; i++) {
const str = sourceStr.substr(i, 1)
if (keep && enReg.test(str)) {
targetStr += str
} else if (cnReg.test(str)) {
const searchResult = searchPinYin(str, PinYin)
if (searchResult) {
// targetStr += searchResult
targetStr += capitalize(searchResult) // 首字母大寫
}
}
}
return targetStr
}
/**
* 檢索拼音
*
* @param {string} str 源字符串
* @param {object} data 收集的拼音 Unicode 編碼集合
*/
const searchPinYin = (str, data) => {
for (const key in data) {
if (data.hasOwnProperty(key) && data[key].indexOf(str) !== -1) {
return key
}
}
return ''
}
/**
* 將拼音首字母轉(zhuǎn)換為大寫
*
* @param {string} str 源字符串
*/
const capitalize = str => {
if (str) {
const [first] = str
const other = str.replace(/^\S/, '')
return `${first.toUpperCase()}${other}`
}
return str
}
/**
* 目前這個 16 進(jìn)制 Unicode 編碼是網(wǎng)上收集的亚侠,可能不能覆蓋所有的中文字符硝烂,可以自行補(bǔ)充铜幽;
*
* 例如:‘婋’(xiao)字:
* 1、使用 '婋'.charCodeAt(0).toString(16) 得到 Unicode 編碼:5a4b除抛;
* 2、將編碼前面加上:\u => \u5a4b;
* 3橄教、然后放到對象 PinYin['xiao'] 里面护蝶。
*
* 現(xiàn)在只想到了這種笨方法一個一個往里補(bǔ)充,如果有更好的方法持灰,歡迎指出C辈觥!姨涡!
*/
const PinYin = {
a: '\u554a\u963f\u9515'
// ...
// 由于這塊代碼太多,這里省略就不貼上來了赏表,麻煩請看 GitHub Demo匈仗。
}
}
難點
其實在中文轉(zhuǎn)拼音的過程中,比較麻煩的在于多音字
和生僻字
的實現(xiàn)间狂,我想到的解決思路是:
生僻字:是由于
PinYin
里面列舉的缺失一些中文字符火架,可通過str.charCodeAt(0).toString(16)
的方式補(bǔ)充,具體方法不再贅述纺弊,上面有說明骡男。多音字:其實多音字一直是最麻煩的地方,因為每一個中文字符只有一個對應(yīng)的 Unicode 編碼犹菱,所以需要在對象的多個對應(yīng)屬性上添加編碼骚亿。
如曾
字,通過'曾'.charCodeAt(0).toString(16)
獲取到66fe
来屠,然后前面拼接上\u
,得到\u66fe
捆姜。
// 截取 PinYin 一小部分
const PinYin = {
ceng: '\u66fe',
zeng: '\u66fe'
}
然后修改上述 convert2Pinyin()
和 searchPinYin()
方法迎膜,把符合規(guī)則的字符返回一個數(shù)組,然后用排列組合的方式列出所有可能珊豹。
GitHub
該倉庫除了拼音轉(zhuǎn)中文之外,還有其他實用方法蜕便,麻煩移步查看贩幻。如有更好的實現(xiàn)方法,歡迎留言族壳,謝謝仿荆!