Lua中特殊字符過濾(UTF8編碼)

Table of Contents

  1. 提綱
    1. 思路
    2. 中文Unicode
    3. Unicode和UTF8的聯(lián)系
    4. 常見特殊字符
    5. 過濾特殊字符
  2. 思路
  3. 中文Unicode編碼
  4. 根據(jù)字符的UTF8編碼獲取Unicode
  5. 需要過濾掉的特殊字符
  6. 代碼實現(xiàn)

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

提綱

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

思路

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

中文Unicode

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

Unicode和UTF8的聯(lián)系

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

常見特殊字符

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

過濾特殊字符

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

思路

常見的特殊字符有很多,查了很多資料,沒找到特殊字符的Unicode編碼范圍,即使找到了也難以保證覆蓋了全部。因此只能從非的角度考慮, 實現(xiàn)目標(biāo)是留下操作系統(tǒng)支持的可作為文件名的字符。

<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">字?jǐn)?shù)</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">漢字結(jié)構(gòu)</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>

根據(jù)字符的UTF8編碼獲取Unicode

UTF8和Unicode的關(guān)系網(wǎng)上資料很多, 在此不再贅述,簡而言之,中文的UTF8編碼都是三個字節(jié),1110xxxx 10xxxxxx 10xxxxxx, 剩余的16位正好放下Unicode編碼的兩個字節(jié),因此只要取出這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. 兩個字節(jié)的UTF
  3. UTF編碼在四個字節(jié)及四個字節(jié)以上的字符

可以使用此頁面內(nèi)的特殊字符進行測試: https://wenku.baidu.com/view/fddf6408844769eae009ed14.html?re=view

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

代碼實現(xiàn)

-- 過濾中文特殊字符
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
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • UTF-8 編碼提供了一種簡便而向后兼容的方法, 使得那種完全圍繞 ASCII 設(shè)計的操作系統(tǒng), 比如 Unix,...
    謝大見閱讀 5,003評論 0 3
  • 目前計算機中用得最廣泛的字符集及其編碼 ASCII,unicode,utf8,big5,gb2312,gbk,gb...
    passiony閱讀 2,844評論 0 2
  • 在軟件的編碼和實現(xiàn)中,我們可能會碰到個一個比較頭疼的問題--編碼,不同字符間的編碼和解碼,你確定了解各種字符的編碼...
    Java小鋪閱讀 2,629評論 0 5
  • 在現(xiàn)在信息爆炸的時代,能否獲取到關(guān)鍵信息顯得格外的重要。打個最簡單的例子,最近暴雨連綿不斷,如果不能及時知道黃色警...
    掃地_閱讀 392評論 0 6
  • 這個就是我的妹妹 我的妹妹她今年六歲左右,她是一個活潑可愛,調(diào)皮搗蛋的小朋友。時而可愛,時而頑皮,大家都拿...
    夕顏_農(nóng)卡閱讀 280評論 2 1

友情鏈接更多精彩內(nèi)容