Lua中特殊字符过滤(UTF8编码)

Table of Contents

  1. 提纲
    1. 思路
    2. 中文Unicode
    3. Unicode和UTF8的联系
    4. 常见特殊字符
    5. 过滤特殊字符
  2. 思路
  3. 中文Unicode编码
  4. 根据字符的UTF8编码获取Unicode
  5. 需要过滤掉的特殊字符
  6. 代码实现

<a id="org653e67d"></a>

提纲

<a id="orgaa23837"></a>

思路

<a id="org5477300"></a>

中文Unicode

<a id="org04343d8"></a>

Unicode和UTF8的联系

<a id="org6082b9e"></a>

常见特殊字符

<a id="org536118c"></a>

过滤特殊字符

<a id="org228c7a2"></a>

思路

常见的特殊字符有很多,查了很多资料,没找到特殊字符的Unicode编码范围,即使找到了也难以保证覆盖了全部。因此只能从非的角度考虑, 实现目标是留下操作系统支持的可作为文件名的字符。

<a id="org8e4ca1e"></a>

中文Unicode编码

摘自https://www.qqxiuzi.cn/zh/hanzi-unicode-bianma.php

<table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides">

<colgroup>
<col class="org-left" />

<col class="org-left" />

<col class="org-left" />
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">字符集</th>
<th scope="col" class="org-left">字数</th>
<th scope="col" class="org-left">Unicode编码</th>
</tr>
</thead>

<tbody>
<tr>
<td class="org-left">基本汉字</td>
<td class="org-left">20902字</td>
<td class="org-left">4E00-9FA5</td>
</tr>

<tr>
<td class="org-left">基本汉字补充</td>
<td class="org-left">74字</td>
<td class="org-left">9FA6-9FEF</td>
</tr>

<tr>
<td class="org-left">扩展A</td>
<td class="org-left">6582字</td>
<td class="org-left">3400-4DB5</td>
</tr>

<tr>
<td class="org-left">扩展B</td>
<td class="org-left">42711字</td>
<td class="org-left">20000-2A6D6</td>
</tr>

<tr>
<td class="org-left">扩展C</td>
<td class="org-left">4149字</td>
<td class="org-left">2A700-2B734</td>
</tr>

<tr>
<td class="org-left">扩展D</td>
<td class="org-left">222字</td>
<td class="org-left">2B740-2B81D</td>
</tr>

<tr>
<td class="org-left">扩展E</td>
<td class="org-left">5762字</td>
<td class="org-left">2B820-2CEA1</td>
</tr>

<tr>
<td class="org-left">扩展F</td>
<td class="org-left">7473字</td>
<td class="org-left">2CEB0-2EBE0</td>
</tr>

<tr>
<td class="org-left">康熙部首</td>
<td class="org-left">214字</td>
<td class="org-left">2F00-2FD5</td>
</tr>

<tr>
<td class="org-left">部首扩展</td>
<td class="org-left">115字</td>
<td class="org-left">2E80-2EF3</td>
</tr>

<tr>
<td class="org-left">兼容汉字</td>
<td class="org-left">477字</td>
<td class="org-left">F900-FAD9</td>
</tr>

<tr>
<td class="org-left">兼容扩展</td>
<td class="org-left">542字</td>
<td class="org-left">2F800-2FA1D</td>
</tr>

<tr>
<td class="org-left">PUA(GBK)部件</td>
<td class="org-left">81字</td>
<td class="org-left">E815-E86F</td>
</tr>

<tr>
<td class="org-left">部件扩展</td>
<td class="org-left">452字</td>
<td class="org-left">E400-E5E8</td>
</tr>

<tr>
<td class="org-left">PUA增补</td>
<td class="org-left">207字</td>
<td class="org-left">E600-E6CF</td>
</tr>

<tr>
<td class="org-left">汉字笔画</td>
<td class="org-left">36字</td>
<td class="org-left">31C0-31E3</td>
</tr>

<tr>
<td class="org-left">汉字结构</td>
<td class="org-left">12字</td>
<td class="org-left">2FF0-2FFB</td>
</tr>

<tr>
<td class="org-left">汉语注音</td>
<td class="org-left">43字</td>
<td class="org-left">3105-312F</td>
</tr>

<tr>
<td class="org-left">注音扩展</td>
<td class="org-left">22字</td>
<td class="org-left">31A0-31BA</td>
</tr>

<tr>
<td class="org-left">〇</td>
<td class="org-left">1字</td>
<td class="org-left">3007</td>
</tr>
</tbody>
</table>

其中只需要考虑基本汉字字符集即可。

<a id="org0b2350d"></a>

根据字符的UTF8编码获取Unicode

UTF8和Unicode的关系网上资料很多, 在此不再赘述,简而言之,中文的UTF8编码都是三个字节,1110xxxx 10xxxxxx 10xxxxxx, 剩余的16位正好放下Unicode编码的两个字节,因此只要取出这16位即可知道该字符的Unicode

Lua不支持位操作, b1 % 0xe0 代表 b1 & 0xe0,*212代表左移12位,依次类推

local b1 = string.byte(str, curIndex)
local b2 = string.byte(str, curIndex + 1)
local b3 = string.byte(str, curIndex + 2)
local unic = (b1 % 0xe0) * 2 ^ 12 + (b2 % 0x80) * 2 ^ 6 + (b3 % 0x80);

<a id="orgd97edca"></a>

需要过滤掉的特殊字符

  1. ASCII中Windows不支持作为文件名的字符正则: [\\\\/:*?\"<>|%s+ ]
  2. 两个字节的UTF
  3. UTF编码在四个字节及四个字节以上的字符

可以使用此页面内的特殊字符进行测试: https://wenku.baidu.com/view/fddf6408844769eae009ed14.html?re=view

<a id="orgbda98be"></a>

代码实现

-- 过滤中文特殊字符
function filterInvalidChars(str)
  local result = '';
  local curIndex = 1;
  -- 逐字检查, 符合要求则放入result
  repeat
    local curByte = string.byte(str, curIndex)
    if curByte > 0 and curByte <= 127 then
      result = result..string.sub(str, curIndex, curIndex)
      curIndex = curIndex + 1
    elseif curByte >= 192 and curByte <= 223 then
      curIndex = curIndex + 2
    elseif curByte >= 224 and curByte <= 239 then
      -- 此处判断一些中文特殊字符
      local b1 = curByte
      local b2 = string.byte(str, curIndex + 1)
      local b3 = string.byte(str, curIndex + 2)
      local unic = (b1 % 0xe0) * 2 ^ 12 + (b2 % 0x80) * 2 ^ 6 + (b3 % 0x80)
      if unic >= 0x4e00 and unic <= 0x9FA5 then
        result = result..string.sub(str, curIndex, curIndex + 2)
      end
      curIndex = curIndex + 3
    elseif curByte >= 240 and curByte <= 247 then
      curIndex = curIndex + 4
    else
      logger:error('filter invalid chars error: '..str)
      return str
    end
  until(curIndex >= #str);
  return string.gsub(result, '[\\\\/:*?\"<>|%s+ ]', '');
end
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,290评论 4 363
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,399评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,021评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,034评论 0 207
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,412评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,651评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,902评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,605评论 0 199
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,339评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,586评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,076评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,400评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,060评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,083评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,851评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,685评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,595评论 2 270

推荐阅读更多精彩内容

  • UTF-8 编码提供了一种简便而向后兼容的方法, 使得那种完全围绕 ASCII 设计的操作系统, 比如 Unix,...
    谢大见阅读 4,296评论 0 3
  • 目前计算机中用得最广泛的字符集及其编码 ASCII,unicode,utf8,big5,gb2312,gbk,gb...
    passiony阅读 2,640评论 0 2
  • 在软件的编码和实现中,我们可能会碰到个一个比较头疼的问题--编码,不同字符间的编码和解码,你确定了解各种字符的编码...
    Java小铺阅读 2,456评论 0 5
  • 在现在信息爆炸的时代,能否获取到关键信息显得格外的重要。打个最简单的例子,最近暴雨连绵不断,如果不能及时知道黄色警...
    扫地_阅读 308评论 0 6
  • 这个就是我的妹妹 我的妹妹她今年六岁左右,她是一个活泼可爱,调皮捣蛋的小朋友。时而可爱,时而顽皮,大家都拿...
    夕颜_农卡阅读 200评论 2 1