Lua 截取字符串(截取utf-8格式字符串)


對utf-8完全沒概念的可以看看我上一篇隨筆:簡單說說utf-8編碼格式

另外,還要知道string.sub 和 string.byte 的用法。

 

 

先上完整代碼:

local  StringHelper = {} --[[ utf-8編碼規則 單字節 - 0起頭 1字節 0xxxxxxx 0 - 127 多字節 - 第一個字節n個1加1個0起頭 2 字節 110xxxxx 192 - 223 3 字節 1110xxxx 224 - 239 4 字節 11110xxx 240 - 247 可能有1-4個字節 --]]
function StringHelper.GetBytes(char) if not char then
      return 0
   end
   local code = string.byte(char) if code < 127 then
      return 1
   elseif code <= 223 then
      return 2
   elseif code <= 239 then
      return 3
   elseif code <= 247 then
      return 4
   else
      -- 講道理不會走到這里^_^
      return 0
   end
end

function StringHelper.Sub(str, startIndex, endIndex) local tempStr = str local byteStart = 1 -- string.sub截取的開始位置
   local byteEnd = -1 -- string.sub截取的結束位置
   local index = 0  -- 字符記數
   local bytes = 0  -- 字符的字節記數
 startIndex = math.max(startIndex, 1) endIndex = endIndex or -1
   while string.len(tempStr) > 0 do     
      if index == startIndex - 1 then byteStart = bytes+1; elseif index == endIndex then byteEnd = bytes; break; end bytes = bytes + StringHelper.GetBytes(tempStr) tempStr = string.sub(str, bytes+1) index = index + 1
   end
   return string.sub(str, byteStart, byteEnd) end

 

基本思路:

之所以要自己寫一個截取函數,是因為lua的庫函數string.sub實際是字節的截取函數。

uft-8編碼格式中,大部分中文是3個字節表示的,數字和字母等是一個字節的,還有某些國家的語言是2字節的,直接用string.sub就可能截出亂碼來,因為不確定要截多少個字節。

所以,

定義一個GetBytes函數,獲取字符的字節數(根據首個字節的高位標記,判斷是幾字節的字符)

然后不斷后移,記錄字節數和字符數。

如上圖,假設要取字符3-4,那么應該從第3個字符的第一個字節取到第4個字最后一個字節

即:

當前字符數為截取的起始字符(startIndex)前一個位置時,說明從下一個字節開始截取字符串   即 index == startIndex - 1 時 byteStart = bytes+1

當前字符數為截取的終止字符(endIndex)時,說明要截取的字符串到此為止   即 index == endIndex 時 byteEnd = bytes

用 string.sub(str, byteStart, byteEnd) 就能截取byteStart 到 byteEnd 的字節

 

測試代碼:

str = "中1文*a字符串勉強します";
print(StringHelper.Sub(str, 3, 4))
print(StringHelper.Sub(str, 1, 4))
print(StringHelper.Sub(str, 8))
print(StringHelper.Sub(str, 2, 12))

測試結果:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM