JS 繁简转换优化

前已有博客,可优化,以充实转换表,优化查找比对:

基于 JS实现页面字体繁简转换

一、代码重构

源代码过于繁琐、注释过多,可重构。重构过后,保证原作者都看不出来这是基于谁的作品。

(function(){
	//简繁对照表,重构之时与原文一致,故省略
	var zh_t = '皚……';
	var zh_s = '皑……';
	var translated;
	function tradition(s) {
		var s1=zh_s,s2=zh_t;
		var a = '';
		for(var i=0, l=s.length;i<l;i++){
			var c = s.charAt(i);
			var p = s1.indexOf(c)
			a += p < 0 ? c : s2.charAt(p);
		}
		return a;
	}
	
	function simplify(s) {
		var s1=zh_t,s2=zh_s;
		var a = '';
		for(var i=0, l=s.length;i<l;i++){
			var c = s.charAt(i);
			var p = s1.indexOf(c)
			a += p < 0 ? c : s2.charAt(p);
		}
		return a;
	}
	
	function T(s) {
		if(s) {
			var s1=zh_s;
			for(var i=0, l=s.length;i<l;i++){
				if(s1.indexOf(s.charAt(i))) return 1;
			}
		}
		return 0;
	}
	function S(s) {
		if(s) {
			var s1=zh_t;
			for(var i=0, l=s.length;i<l;i++){
				if(s1.indexOf(s.charAt(i))) return 1;
			}
		}
		return 0;
	}
	
	function getNextNode(n, e) {
		var a = n.firstChild;
		if (a) return a;
		while (n && n!=e) {
			if (a = n.nextSibling) {
				return a
			}
			n = n.parentNode
		}
		return 0;
	}
	
	function zhTran(t, rootNode) { // t 为繁简转换类型,可为 0,1,2
		debug('zhTran', rootNode)
		var e=rootNode,n=e, fn=t==1?tradition:simplify, tn=t==1?T:S;
		if(t==0) {
			if(translated) {
				while(n=getNextNode(n,e)) {
					if (n.nodeType==3 && n._zhy) {
						n.data = n._zhy;
						n._zhy = undefined;
					}
				}
				translated = 0;
			}
		} else {
			// detect pass
			while(n=getNextNode(n,e)) {
				if (n.nodeType==1) {
					if(' SCRIPT STYLE LINK IFRAME '.indexOf(' '+n.tagName+' ') > 0)
						continue;
					if (tn(n.title)) break;
					if (tn(n.alt)) break;
					if (n.tagName == "INPUT" && tn(n.value)) 
						break;
				}
				else if (n.nodeType==3 && tn(n.data))
					break;
			}
			translated = !!n;
			// convert pass
			while(n) {
				if (n.nodeType==1) {
					if(' SCRIPT STYLE LINK IFRAME '.indexOf(' '+n.tagName+' ') > 0) {
						n=getNextNode(n,e)
						continue;
					}
					if (n.title) n.title = fn(n.title);
					if (n.alt) n.alt = fn(n.alt);
					if (n.tagName == "INPUT") 
						n.value = fn(n.value);
				}
				else if (n.nodeType==3){
					var data=n.data, text=fn(data);
					if(data!=text) {
						if(!n._zhy) n._zhy = data;
						n.data = text;
					}
				}
				n=getNextNode(n,e)
			}
		}
	}
	function zh_tran(t) {
		zhTran(t, document.body);
	}
	window.zh_tran = zh_tran;
})()

解释:代码0表示不转换,1表示转换为繁体,2表示转换为简体。

至于节点遍历,替换原文的递归遍历(zh_tranBody)为基于nextSibling的单循环节点遍历(getNextNode),思想学自 rangy.js

	function getNextNode(n, e) { // 获得当前节点n的下一节点。 n 为当前节点, e 为终止节点(父容器)
		var a = n.firstChild;
		if (a) return a;
		while (n && n!=e) {
			if (a = n.nextSibling) {
				return a
			}
			n = n.parentNode
		}
		return 0;
	}

附基准测试:Benchmark: childNodes vs children vs firstChild/nextSibling vs firstElementChild/nextElementSibling - MeasureThat.net

转换流程:先用大写的方法T、S测试,检测是否需要页面转换为目标(繁、简)字体。如需转换,再分别调用转换方法。

		var fn=t==1?tradition:simplify, tn=t==1?T:S;

二、充实简繁对照表

原文转换表只有1275字,且不包含多个繁体对应同一简体的情况。我综合了github上一个python库和一个java库的字表,得两千多字,且包含一百多个N对1的情况:

个個箇
为為爲
么幺麼麽
产產産
仑侖崙
众眾衆
伪偽僞
冲沖衝
净凈淨
凫鳧鳬
别別彆
勋勛勳
升昇陞
卤鹵滷
历歷厤曆
厕廁厠
参參蔘
发發髮
只衹隻
台檯臺颱
叹嘆歎
向嚮曏
启啟啓
团團糰
坛壇墰壜罈罎
墙牆墻
壳殼殻
复復複
奖獎奬
妫媯嬀
尝嘗嚐
尽盡儘
干乾幹榦
并並併
弥彌瀰
当當噹
录錄録
恶惡噁
悫愨慤
戚慼鏚
曲麯麴
术術朮
榉櫸欅
毁毀燬譭
汇匯彙滙
沩溈潙
溯泝遡
炼煉鍊
画畫畵
瘘瘺瘻
竖豎竪
签簽籤
系係繫
纤纖縴
线線綫
绝絕絶
绣綉繡
绦絛縧
绱緔鞝
绷綳繃
绿綠緑
缰韁繮
胡衚鬍
脏臟髒
艳艷豔
苏蘇囌甦
荡盪蕩
药葯藥
获獲穫
莼蒓蓴
蒙懞矇
蕴蘊藴
说說説
谣謠謡
谫譾謭
赃贓贜
赍齎賫
赝贗贋
赞贊讚
酝醞醖
采埰寀採
里裏裡
鉴鑒鑑
钟鍾鐘
钩鈎鉤
钵缽鉢
铲鏟剷
锈銹鏽
锐銳鋭
锤錘鎚
锨杴鍁
镌鐫鎸
镢钁鐝
镰鐮鎌
闲閑閒
阅閱閲
面麪麫麵
须須鬚
颓頹頽
颜顏顔
饥飢饑
骂罵駡
鲇鯰鮎
鲞鯗鮝
鳄鱷鰐
鸡雞鷄
鹚鶿鷀

三、优化查找

原查找方法仅仅是基于js的字符串查找(indexOf),可替换为二分法查找,提高效率。当转换为繁体,而存在“N繁体对应1简体”的情况时,可手动将更常用的一对排前面,二分法能查到首个大于等于查询键值的位置。

不过二分法所需容量过多、步骤繁琐,所以干脆用Map了

四、小结

通过充实字表,可以转换更多繁体为简体。通过采用二分法,可以有效提升效率。群里还有人发给我更详细的字表,六千多对,不过许多字都显示为方框了。

仍有不足,当存在N对1的情况下,无法判断哪一对是正确的。所以转换结果仅供参考。

五、源代码

源代码备份在无限词典asset文件夹中的zh.js之中。字表备份于Kasemap.ali

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
模仿语言包式的简繁转换功能插件,轻松实现繁体和简体互换,很方便,只有一个JS文件。Std_StranJF.js文件只支持GB2312码,big52gb.js支持utf-8。   一、将繁简互换JS文件上传至空间:   如果您调用的是,则将繁简互换JS文件(Std_StranJF.Js)上传至网站的js目录中。当然您也可以上传至网站的其他何地方,如根目录下。如果上传在网站根目录下,则要将调用代码改成:   二、页面调用的方法:   在您的网站中请按以下方法添加以下的代码:   1. 在页面中加上以下链接:   繁体中文   这个是每个页面中显示进行简繁转换的链接,您可以放在页面顶部,如顶部的导航处。   如果您用的是默认的动易模板,则进入网站后台,依次点击“系统设置”->“自定义标签管理”->“2006海蓝”->“{$MY_动易2006海蓝首页顶}”->点击“修改”链接,在出现的自定义标签内容页面中,找到“{$ShowChannel} {$Rss}{$Wap}”,修改成“{$ShowChannel} |繁体中文|{$Rss}{$Wap}”即可。当然您也可以放在任何您想要放置的地方。   2. 在页面中放以下代码:      这个是每个页面中要调用繁体和简体互换的JS代码,您放在页面底部,如前面。   如果您用的是默认的动易模板,则进入网站后台,依次点击“系统设置”->“自定义标签管理”->“2006海蓝”->“{$MY_动易2006海蓝网页底}”->点击“修改”链接,在出现的自定义标签内容页面中,找到“”,修改成“”即可。当然您也可以放在任何您想要放置的地方。   小提示:您也可以不修改自定义标签,而是通过系统模板批量替换功能来添加以上的代码。但利用修改模板的自定义标签内容更方便。在修改了自定义标签后要记得更新您网站的缓存。若您开启了网站的生成功能,则在添加了代码后要生成全部相关的页面。   三、繁简互换JS文件参数的修改:   您可以进一步修改繁简互换JS文件(Std_StranJF.Js)以达到您想要的效果。请以记事本打开修改Std_StranJF.Js文件:   var Default_isFT = 0 //默认是否繁体,0-简体,1-繁体   var StranIt_Delay = 50 //翻译延时毫秒(设这个的目的是让网页先流畅的显现出来)   同时如果您的网站中有本文件中没有放入的繁体与简体互换的内容,则可以在本文件中进一步添加与扩充,以满足您的应用需求。   小提示:本插件同时可用于论坛等需要进行繁简互换的地方。
实现简繁体互转可以使用一些现有的 JavaScript 库,例如 OpenCC 和 Hanzi.js。 使用 OpenCC 库,可以这样实现简繁体互转: 1. 安装 OpenCC 库: ```javascript npm install opencc ``` 2. 引入 OpenCC 库: ```javascript const OpenCC = require('opencc'); ``` 3. 创建一个 OpenCC 实例: ```javascript const converter = new OpenCC('s2t.json'); ``` 4. 使用 `convertSync` 方法将简体转换为繁体: ```javascript const traditionalText = converter.convertSync('简体中文'); console.log(traditionalText); // 簡體中文 ``` 5. 使用 `convertSync` 方法将繁体转换为简体: ```javascript const simplifiedText = converter.convertSync('繁體中文'); console.log(simplifiedText); // 简体中文 ``` 使用 Hanzi.js 库,可以这样实现简繁体互转: 1. 安装 Hanzi.js 库: ```javascript npm install hanzi ``` 2. 引入 Hanzi.js 库: ```javascript const Hanzi = require('hanzi'); ``` 3. 使用 `isSimplified` 方法判断一个字符是否为简体: ```javascript const isSimplifiedChar = Hanzi.isSimplified('中'); console.log(isSimplifiedChar); // true ``` 4. 使用 `isTraditional` 方法判断一个字符是否为繁体: ```javascript const isTraditionalChar = Hanzi.isTraditional('中'); console.log(isTraditionalChar); // false ``` 5. 使用 `simplify` 方法将繁体转换为简体: ```javascript const simplifiedText = Hanzi.simplify('繁體中文'); console.log(simplifiedText); // 简体中文 ``` 6. 使用 `traditionalize` 方法将简体转换为繁体: ```javascript const traditionalText = Hanzi.traditionalize('简体中文'); console.log(traditionalText); // 繁體中文 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值