参考链接:

https://baike.baidu.com/item/%E5%AD%97%E7%AC%A6%E7%BC%96%E7%A0%81/8446880?fr=aladdin#7

http://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html

http://blog.csdn.net/r0ck_y0u/article/details/51883955

一.字符编码

字符编码的发展史:ASCII->Unicode->UTF-8

1.ASCII:ASCII码可以表示所有的英语字符(字母、数字、标点符号等)。ASCII码是7位编码(0-127),但由于计算机基本处理单位为字节(1字节=8位),所以一个ASCII字符占一个字节。

2.Unicode:因为一个ASCII字符只能表示256个字符,显然是存在着局限的(如不能用来表示中文)。而且不同的语言有不同的字符,为了让世界上所有的字符都有一个唯一的编码值(如果一个编码值对应多个字符,就会出现歧义),就出现了Unicode码。Unicode码可以容纳100多万个符号,每个符号的编码都不一样。但是Unicode码的缺点是效率不高,比如UCS-4(Unicode的标准之一)规定用4个字节存储一个符号,那么每个英文字母前都必然有三个字节是0,原本只需1个字节现在却用了4个字节,这对存储和传输来说都很耗资源。

3.UTF-8:为了提高Unicode的编码效率,于是就出现了UTF-8编码。UTF-8可以根据不同的符号自动选择编码的长短。在UTF-8中,一个英文占1个字节,一个中文占3个字节。

二.string库

相关api:http://cloudwu.github.io/lua53doc/manual.html#pdf-string.sub

在lua中,string库都是针对单字节字符编码的。在UTF-8中,因为英语字符都是单字节字符,所以使用string库处理英语字符是没有问题的;但是中文字符是多字节字符,如果使用string库去处理是不行的。

 --UTF-8编码,一个中文占3个字节
local a1 = "你好啊a" print(string.byte(a1,,))--第1到第4个字节
print(string.len(a1))--字节总数
local startIndex, endIndex = string.find(a1, "你好")
print(startIndex .. " " .. endIndex)--第1到第6个字节 print("----------------------------------------------------")
local test = "泰"
local test2 = "法?" print(string.len(test))
print(string.byte(test,,))
print(string.byte(test2,,)) --string.gsub的第二个参数为正则表达式,?表示匹配0个至1个
--字节230179176中的230179被替换成989898
local str = string.gsub(test, test2, function()
print("gsub success!")
return "bbb"
end)
print(str)
print(string.byte(str,,))
print(string.byte("b",,))

输出如下:

三.中文处理

先来测试一下中文是怎样匹配的:

 --为了方便输出中文,这里使用ANSI编码
--在ANSI编码中,1个中文占2个字节
local test = "泰ab"
local result print(string.byte(test,,))--泰:204169 a:97 b:98
print(type(string.byte(test,,)))--数字 --string.gsub 逐字节匹配
print("1.")
result = string.gsub(test, "[204169]", "c")
print(result)--[204169]:2,0,4,1,6,9的集合,因此匹配失败 print("2.")
result = string.gsub(test, "[\204169]", "c")
print(result)
print(string.byte(result,,))--第1个字节204匹配成功
print(string.byte("゛",,))--c:99 ゛:16997 b:98 print("3.")
result = string.gsub(test, "[\204\169]", "c")
print(result)--匹配成功2次 print("4.")
result = string.gsub(test, "[\204][\169]", "c")
print(result)--匹配成功1次,将原字符串中的中文替换了

输出如下:

UTF8的编码规则:

1.字符的第一个字节范围:(0-127)、(194-244)

2.字符的第二个字节及以后范围(针对多字节编码,如汉字):(128-191)

3.(192,193和245-255)不会出现在UTF8编码中

根据以上规则就可以得出处理中文的方法了:

 --获取字符数
function GetWordCount(str)
local _,count = string.gsub(str, "[^\128-\193]", "")
return count
end --将字符串转为table
function GetWordTable(str)
local temp = {}
for uchar in string.gmatch(str, "[%z\1-\127\194-\244][\128-\191]*") do
temp[#temp+] = uchar
end
return temp
end --utf8
local test = "泰ab好了." print(GetWordCount(test))
local testT = GetWordTable(test) --%z:匹配0 *:表示0个至任意多个
for i=,#testT do
print(testT[i])
end

四.敏感字处理

敏感字的处理主要体现在取名、聊天上,如果字符串中含有敏感字,则需要将其替换成“*”。一开始我使用的string.gsub方法,但是发现敏感字中有不少是带有特殊符号,从而使整个字符串变成了一个正则表达式了,发生了正则匹配的错误,而正确的做法应该是直接跟敏感字进行对比。后来采用的是string.find方法,因为它可以关闭正则匹配。

 local sensitiveWordConfig = {"法?"};

 function GetWordCount(str)
local _, count = string.gsub(str, "[^\128-\193]", "")
return count;
end --内部接口:将字符串中的敏感字替换成*(替换一个)
function ReplaceSensitiveWord(originStr, sensitiveWord)
local resultStr = originStr;
--1:从索引1开始搜索 true:关闭模式匹配
local startIndex, endIndex = string.find(originStr, sensitiveWord, , true);
if (startIndex and endIndex) then
local strLen = string.len(originStr);
local maskWordCount = GetWordCount(sensitiveWord);
local maskWord = "";
for i=,maskWordCount do
maskWord = maskWord .. "*";
end
-- print(string.format("startIndex: %d endIndex: %d", startIndex, endIndex));
-- print(string.format("strLen: %s maskWord: %s", strLen, maskWord)); if (startIndex == ) then
resultStr = maskWord .. string.sub(originStr, endIndex + , -);
elseif (endIndex == strLen) then
resultStr = string.sub(originStr, , startIndex - ) .. maskWord;
else
local str = string.sub(originStr, ,startIndex - );
local str2 = string.sub(originStr, endIndex + , -);
resultStr = str .. maskWord .. str2;
end
end
return resultStr;
end --内部接口:将字符串中的敏感字替换成*(替换所有)
function ReplaceSensitiveWordAll(originStr, sensitiveWord)
local str = originStr;
local str2 = ReplaceSensitiveWord(originStr, sensitiveWord);
while (str ~= str2) do
str = str2;
str2 = ReplaceSensitiveWord(str2, sensitiveWord);
end
return str2;
end --内部接口:是否有该敏感字
function HasSensitiveWord(originStr, sensitiveWord)
local startIndex, endIndex = string.find(originStr, sensitiveWord, , true);
if (startIndex and endIndex) then
-- print("敏感字:" .. sensitiveWord);
return true;
else
return false;
end
end --外部接口:敏感字替换
function ReplaceMaskWord(content)
for k,v in pairs(sensitiveWordConfig) do
content = ReplaceSensitiveWordAll(content, v);
end
return content;
end --外部接口:是否有敏感字
function HasMaskWord(content)
for k,v in pairs(sensitiveWordConfig) do
if (HasSensitiveWord(content, v)) then
return true;
end
end
return false;
end print(ReplaceSensitiveWord("法?123法?", "法?"));
print(ReplaceSensitiveWordAll("法?123法?", "法?"));
print(HasSensitiveWord("12中法?3文", "法?"));
print(ReplaceMaskWord("1法?法?2"));
print(HasMaskWord("1法?法?2"));

[Lua]string与中文的更多相关文章

  1. Lua string库整理

    string库提供了字符串处理的通用函数. 例如字符串查找.子串.模式匹配等. 当在 Lua 中对字符串做索引时,第一个字符从 1 开始计算(而不是 C 里的 0 ). 索引可以是负数,它指从字符串末 ...

  2. Lua 5.2 中文参考手册

    闲来无事,发现Lua更新到了5.2.2,参考手册也更到了5.2,在网上发现只有云风翻译的5.1版,花了几天时间翻译了一些. 参考手册有点长,又要随时修改,所以在github上建了项目,有需要的朋友可以 ...

  3. lua string.byte怎么判断是中文还是别的

    string.byte(char)>127是中文,string.sub(s,i,i+2),占两个字节,中文 string.byte(char)<=127是普通字符,咱一个字节

  4. lua中的中文乱码

    最近在用lua, 发现一个有点意思的槽点啊-____-! 那就是lua貌似会使用系统所用的字符集. 具体点说, 就是在windows上, 它会使用cp936来表示代码中的中文. 来个例子: print ...

  5. (转) Lua string 操作函数

    本文转自: http://www.cnblogs.com/newlist/p/3649388.html table.keys 返回指定表格中的所有键. 格式: keys = table.keys(表格 ...

  6. lua string函数

    lua的string函数: 参数中的index从1开始,负数的意义是从后开始往前数,比如-1代表最后一个字母 对于string类型的值,可以使用OO的方式处理,如string.byte(s.i)可以被 ...

  7. java 读取文件到String(解决中文乱码)

    在改写V&View(维视)时用到了文件管理,需要从html文档读取字符串,可是一直出现中文乱码,一直解决不了.而且很是意外,我在本地运行代码时就能正常读取中文,当放到tomcat上时全是乱码, ...

  8. lua string 库

    --lua中字符串索引从前往后是1,2,……,从后往前是-1,-2……. --string库中所有的function都不会直接操作字符串,只返回一个结果. ---------------------- ...

  9. lua string.sub截取中英文

    cocos2dx 2.x环境,要做一个截取很长的字符串的前100个字符显示的小功能. PC环境ok,出了ios包发现有时候这个字符串会显示不出,猜测了下可能是跟中文字在lua里每个字占3个字符有关,举 ...

随机推荐

  1. 【转】Python metaclass

    转自: http://ju.outofmemory.cn/entry/32434 在回答了 yield关键字和 decorator的问题之后,我更明白了,我决定非常详细地回答这个问题. 读前警告:这个 ...

  2. Kafka三款监控工具比较

    在之前的博客中,介绍了Kafka Web Console这个监控工具,在生产环境中使用,运行一段时间后,发现该工具会和Kafka生产者.消费者.ZooKeeper建立大量连接,从而导致网络阻塞.并且这 ...

  3. 搭建Cordova + Ionic + WebStorm环境开发Web App应用

    1. 下载并且安装Node.js(https://nodejs.org/en/) 2. 打开终端,安装cordova (如果安装失败或者卡住不动则重新安装)    sudo npm install - ...

  4. 【转】mysql给root开启远程访问权限,修改root密码

    好记性不如烂笔头,偶然用一直忘.... mysql给root开启远程访问权限,修改root密码   1.MySql-Server 出于安全方面考虑只允许本机(localhost, 127.0.0.1) ...

  5. url参数的转码和解码

    encodeURI(str) //转码 decodeURI(str)//解码

  6. 玄学曲线并不玄 教你如何看懂GPU呈现

    红色代表了“执行时间”,它指的是Android渲染引擎执行盒子中这些绘制命令的时间,假如当前界面的视图越多,那么红色便会“跳”得越高.实际使用中,比如我们平时刷淘宝App时遇到出现多张缩略图需要加载时 ...

  7. 使用RetionalRose根据现有的java工程逆向生成类图

    1.进入RetionalRose选择J2EE模板 2.在菜单栏选择tools->java/j2EE->reverse engineer 3.编辑路径Edit CLASSPATH选择要生成类 ...

  8. Wireshark抓包工具--TCP数据包seq ack等解读

    1.Wireshark的数据包详情窗口,如果是用中括号[]括起来的,表示注释,在数据包中不占字节 2.在二进制窗口中,如“DD 3D”,表示两个字节,一个字节8位 3.TCP数据包中,seq表示这个包 ...

  9. 产品使用的前后台框架API-dubbo-redis-elasticsearch-jquery

    前台框架API •jQuery:https://jquery.com/ •jQuery MiniUI:http://www.miniui.com/ •Bootstrap:http://www.boot ...

  10. python: 面向对象:类和对象调用类中的变量和方法

    一. 面向对象初识 我们在生活中做事都是面向过程的,前面实现一些基本逻辑功能代码也是用面向过程的语句实现的,后来学了函数,把这些功能又装到了函数里.但用面向过程的方法去写程序,只能实现一个功能,我们要 ...