lua匹配UTF-8中文汉字

版权声明:博客将逐步迁移到 http://cwqqq.com https://blog.csdn.net/cwqcwk1/article/details/51303353
lua5.3虽然支持utf-8,但是自带的string库不支持汉字的处理,而且lua的 正则实现也比较鸡肋,很难匹配中文。所以文章讨论UTF-8字符集,中文汉字的表示方法,然后说明lua 如何匹配UTF-8中文汉字。

初识UTF-8

UTF-8是Unicode的一种实现,是一种变长字节编码方式。对于某一个字符的UTF-8编码,如果只有一个字节则其最高二进制位为0;如果是多字节,其第一个字节从最高位开始,连续的二进制位值为1的个数决定了其编码的位数,其余各字节均以10开头。UTF-8最多可用到6个字节。 
如表:

因此,UTF-8可以用来表示字符编码 最多的有效位数是31位,即x代表的位。除掉那些标志位(如每字节开头的10),UTF-8表示的与 Unicode编码是对应的。
另外,Unicode兼容标准的ASCII字符集,只需要一个字节就可以表示所有ASCII码,ASCII码一共规定了128个字符的编码,所以实际只要7位表示。而对于1字节表示的UTF-8编码,字节开头是0,所以UTF-8表示的英文数字,跟ASCII字符集表示的是一样的。


中文UTF-8

通常都说到,汉字范围从0x4E00到0x9FA5,这是指Unicode编码。对于UTF-8还要做转换。
其中,0x4E00 用二进制表示为  100111000000000
换成UTF-8码就是  11100 100  10 111000  10 000000,即 228, 184, 128
同理, 0x9FA5为  11101001  10 111110  10 100101,即 233, 190, 165
可以看出,中文UTF-8编码用3个字节表示。


lua匹配UTF-8汉字

前面分析了中文UTF-8的编码范围了,所以lua只要用 string.byte(s, i) 取到字符的byte值(字符集通常记 code point)。比较第一个字节是228-233,而且接下来两个字节都是 128-191,就可以简单认定为中文了。
这里以一个例子说明,比如我要过滤特殊字符,保留中文、英文和数字。
function filter_spec_chars(s)
	local ss = {}
	local k = 1
	while true do
		if k > #s then break end
		local c = string.byte(s,k)
		if not c then break end
		if c<192 then
			if (c>=48 and c<=57) or (c>= 65 and c<=90) or (c>=97 and c<=122) then
				table.insert(ss, string.char(c))
			end
			k = k + 1
		elseif c<224 then
			k = k + 2
		elseif c<240 then
			if c>=228 and c<=233 then
				local c1 = string.byte(s,k+1)
				local c2 = string.byte(s,k+2)
				if c1 and c2 then
					local a1,a2,a3,a4 = 128,191,128,191
					if c == 228 then a1 = 184
					elseif c == 233 then a2,a4 = 190,c1 ~= 190 and 191 or 165
					end
					if c1>=a1 and c1<=a2 and c2>=a3 and c2<=a4 then
						table.insert(ss, string.char(c,c1,c2))
					end
				end
			end
			k = k + 3
		elseif c<248 then
			k = k + 4
		elseif c<252 then
			k = k + 5
		elseif c<254 then
			k = k + 6
		end
	end
	return table.concat(ss)
end



最后语

题外话,前面写的过滤特殊字符函数,用lua写效率不高,所以我还写了c的版本,有兴趣 猛击这里


2016/10/14 修复中文匹配bug,感谢sishui的提示
2017/3/2 修正临时变量k不起作用的问题,提升了效率
参考:
http://blog.csdn.net/mycwq/article/details/51303353
http://www.cnblogs.com/chenwenbiao/archive/2011/08/11/2134503.html

猜你喜欢

转载自blog.csdn.net/cwqcwk1/article/details/51303353
今日推荐