不论是浏览器还是操作系统,对中文的支持已经有了长足的进步,但是在一些细节方面仍然存在不足。比如,在windows文件浏览时,我们可以通过按下文件夹名的首字母来快速定位文件夹,但是对于文件夹名为中文的文件夹却无能为力。类似的,在网页浏览中,也存在类似问题。这种问题不会妨碍使用,但却伤害体验。本文分两部分,第一部分简单介绍基于javascript的拼音字典的构造方法;第二部分简单介绍几个应用。
创建基于javascript的拼音字典
之所以基于javascript,是为了获取较高的相应速度,同时减少服务端的压力。我在字典设计时有两个目标:一是查询速度要足够快;二是字典要尽量小。怎么样足够快?数组;怎样尽量小?压缩!好,让我们开始设计吧:
- 字典准备
找一个汉字拼音对照表,用正则表达式将这些汉字与拼音关联起来创建对象字典(为了简单,忽略了多音字)。
结果类似于 a["爱"]='ai',a['我']='wo'…… - 转换为数组
利用汉字具有唯一ascii码值这一特点,将汉字与拼音的对应关系转换为ascii与拼音的对应关系。javascript求中文的ascii码的函数是charCodeAt()。比如'爱'的ascii码是29233,'我'的ascii码是25105……则可以将对象字典转换为数组字典:a[29233]='ai',a[25105]='wo'……
数组字典就完成了。转换以后,要查找爱的拼音,可以这样:a['爱'.charCodeAt()],方便快捷吧? - 压缩数组字典
我使用了三个压缩来压缩字典。
第一个压缩是减小数组空间。因为汉字的ascii值往往比较大,最小的也将近20000。所以我们可以将数组的索引往前平移,我采用的值是18000,为了确保安全,我留出了一定盈余空间。
平移后的数组字典为:a[29233-18000]='ai',a[25205-18000]='wo'……
第二个压缩是减少数据的重复。在字典的近7000个汉字中,读音的种类是较少的。将所有读音种类存到数组b内,然后在数组字典a内记录读音在b中的索引即可。
比如'ai'在b中的索引为1,则数组字典变为 a[11233]=1……
这个时候要查找'爱'的拼音,可以这样 b[a['爱'.charCodeAt()-18000]]
第三个压缩时gzip压缩,这个以后单独在另外的文章中探讨。
经过这几步,简单的字典基本设计好了:字典下载(13k)。这个文件,如果用浏览器直接下载保存,是未Gzip压缩版,约40k。压缩版需要用下载工具下载,约13k。
字典应用举例
我已经将几个应用整理到一个页面中,您可以直接观看效果演示。
- 应用一:汉字排序
JavaScript:
-
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-
<html xmlns= "http://www.w3.org/1999/xhtml">
-
<head>
-
<meta http-equiv= "Content-Type" content= "text/html; charset=utf-8" />
-
<title>Demo@rssidea</title>
-
<script language= "JavaScript" type= "text/javascript" src= "http://demo.rssidea.com/js/ChineseAscii_pack.js"></script>
-
<style type= "text/css">
-
. result {
-
padding:5px 0;
-
margin-bottom:50px;
-
margin-top:10px;
-
border-bottom:1px solid #eee;
-
}
-
</style>
-
</head>
-
<body>
-
<div id= "box">
-
<h3>应用一:汉字排序</h3>
-
<label for= "sortForm">
-
请输入要排序的词组,用半角逗号 (, )隔开。<br />
-
-
<input id= "sortForm" type= "text" size= "70"/><button type= "button" id= "sortBt">开始排序</button>
-
</label>
-
<div class= "result" id= "sortResult">
-
</div>
-
-
</div>
-
<script language= "javascript">
-
var $= function (id ) { return document. getElementById (id ) };
-
var sortForm=$ ( "sortForm" );
-
var sortBt=$ ( "sortBt" );
-
sortBt. onclick= function ( ) {
-
var temp=sortForm. value. split ( ',' );
-
$ ( 'sortResult' ). innerHTML=temp. sort (sortByPinYin ). join ( "," );
-
}
-
</script>
-
</body>
-
</html>
-
- 应用二:汉字注拼音
JavaScript:
-
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-
<html xmlns= "http://www.w3.org/1999/xhtml">
-
<head>
-
<meta http-equiv= "Content-Type" content= "text/html; charset=utf-8" />
-
<title>Demo@rssidea</title>
-
<script language= "JavaScript" type= "text/javascript" src= "http://demo.rssidea.com/js/ChineseAscii_pack.js"></script>
-
<style type= "text/css">
-
. result {
-
padding:5px 0;
-
margin-bottom:50px;
-
margin-top:10px;
-
border-bottom:1px solid #eee;
-
}
-
</style>
-
</head>
-
<body>
-
<div id= "box">
-
<h3>应用二:汉字注拼音</h3>
-
<label for= "translateForm">
-
请输入需要标注拼音的词语或句子。<br />
-
<input id= "translateForm" type= "text" size= "70"/><button type= "button" id= "translateBt">开始注音</button>
-
</label>
-
<div class= "result" id= "tResult">
-
</div>
-
</div>
-
-
</div>
-
<script language= "javascript">
-
var $= function (id ) { return document. getElementById (id ) };
-
var tForm=$ ( "translateForm" );
-
var tBt=$ ( "translateBt" );
-
-
tBt. onclick= function ( ) {
-
var temp=tForm. value. split ( '' ),i=- 1,len=temp. length;
-
while (++i<len ) {
-
temp [i ]= (temp [i ]. charCodeAt ( )< 1000||temp [i ]. charCodeAt ( )> 60000 )?temp [i ]:lookUpWord (temp [i ] );
-
}
-
$ ( 'tResult' ). innerHTML=temp. join ( " " );
-
}
-
</script>
-
</body>
-
</html>
-
- 应用三:关键词筛选
JavaScript:
-
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-
<html xmlns= "http://www.w3.org/1999/xhtml">
-
<head>
-
<meta http-equiv= "Content-Type" content= "text/html; charset=utf-8" />
-
<title>Demo@rssidea</title>
-
<script language= "JavaScript" type= "text/javascript" src= "http://demo.rssidea.com/js/ChineseAscii_pack.js"></script>
-
<style type= "text/css">
-
. result {
-
padding:5px 0;
-
margin-bottom:50px;
-
margin-top:10px;
-
border-bottom:1px solid #eee;
-
}
-
</style>
-
</head>
-
<body>
-
<div id= "box">
-
<h3>应用三:关键词筛选</h3>
-
<label for= "filterForm">
-
请输入字母筛选关键词<br />
-
<input id= "filterForm" type= "text" size= "70"/>
-
</label>
-
<div class= "result" id= "filterResult">
-
北京市 天津市 河北省 山西省 内蒙古自治区
-
辽宁省 吉林省 黑龙江省
-
上海市 江苏省 浙江省 安徽省 福建省 江西省 山东省
-
河南省 湖北省 湖南省 广东省 广西壮族自治区 海南省
-
重庆市 四川省 贵州省 云南省 西藏自治区
-
陕西省 甘肃省 青海省 宁夏回族自治区 新疆维吾尔自治区
-
香港特别行政区 澳门特别行政区 台湾省
-
</div>
-
</div>
-
<script language= "javascript">
-
var $= function (id ) { return document. getElementById (id ) };
-
var keyword=$ ( 'filterResult' ). innerHTML. match ( /[^/s ]+/gi );
-
var j= 0,oriStr= ',';
-
var keywordObj= [ ];
-
while (keyword [j ] ) {
-
var temp=keyword [j ]. split ( '' );
-
var i=- 1,len=temp. length;
-
while (++i<len ) {
-
temp [i ]= (temp [i ]. charCodeAt ( )< 1000||temp [i ]. charCodeAt ( )> 60000 )?temp [i ]:lookUpWord (temp [i ] );
-
}
-
var str=temp. join ( "" );
-
keywordObj [str ]= { };
-
keywordObj [str ]. ori=keyword [j ];
-
oriStr+=str+ ',';
-
j++;
-
}
-
$ ( 'filterForm' ). onkeyup= function ( ) {
-
//alert(this.value);
-
var re= new RegExp ( "//b"+ this. value+ "[^,]+", 'g' );
-
var temp=oriStr. match (re, 'gi' );
-
if (!temp ) {
-
$ ( "filterResult" ). innerHTML= "没有匹配项。";
-
return false;
-
}
-
var j= 0;
-
while (temp [j ] ) {
-
temp [j ]=keywordObj [temp [j ] ]. ori;
-
j++;
-
}
-
$ ( "filterResult" ). innerHTML=temp. join ( " " );
-
}
-
</script>
-
</body>
-
</html>
-