首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 更多程式設計知識

Lua UTF-8 字串長度計算與截斷顯示省略號:雙函式完整實作

     編輯:更多程式設計知識

Lua 原生字串操作以位元組為單位,無法正確處理 UTF-8 多位元組字元。提供兩個實用函式:utfstrlen 計算字元數,GetShortName 依字元寬度截斷並補上省略號。

函式一:utfstrlen — 計算 UTF-8 字元數


function utfstrlen(str)
    local len = #str
    local left = len
    local cnt = 0
    local arr = {0, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC}
    while left ~= 0 do
        local b = string.byte(str, -left)
        local i = #arr
        while arr[i] do
            if b >= arr[i] then left = left - i; break end
            i = i - 1
        end
        cnt = cnt + 1
    end
    return cnt
end

原理:依首位元組最高位判斷字元長度(1~4 位元組),逐字元前進計數。

函式二:GetShortName — 寬度感知截斷


function GetShortName(sName, nMaxCount, nShowCount)
    if not sName or not nMaxCount then return end
    nShowCount = nShowCount or (nMaxCount - 3)
    local tCode, tName = {}, {}
    local nLen = #sName
    local nWidth = 0
    for i = 1, nLen do
        local b = string.byte(sName, i)
        local byteCount = 0
        if b > 0 and b <= 127 then byteCount = 1
        elseif b >= 192 and b < 223 then byteCount = 2
        elseif b >= 224 and b < 239 then byteCount = 3
        elseif b >= 240 and b < 247 then byteCount = 4 end
        local char = byteCount > 0 and string.sub(sName, i, i + byteCount - 1)
        if byteCount == 1 then
            nWidth = nWidth + 1
            table.insert(tName, char); table.insert(tCode, 1)
        elseif byteCount > 1 then
            nWidth = nWidth + 2  -- 中文視為雙寬
            table.insert(tName, char); table.insert(tCode, 2)
        end
        if byteCount > 0 then i = i + byteCount - 1 end
    end
    if nWidth > nMaxCount then
        local out, w = "", 0
        for i = 1, #tName do
            out = out .. tName[i]
            w = w + tCode[i]
            if w >= nShowCount then break end
        end
        return out .. "..."
    end
    return sName
end

使用範例


local str = "Hello世界"
print(utfstrlen(str))           -- 7
print(GetShortName(str, 8, 5))  -- Hello世...
print(GetShortName(str, 10))    -- Hello世界 (未超寬)

設計說明

  • nMaxCount:最大顯示寬度(中文計 2,英文計 1)。
  • nShowCount:截斷前保留寬度,預留 3 寬度給 ...。
  • 適用於 UI 列表、標題欄、聊天訊息預覽等固定寬度場景。

注意

  • 未處理組合字元、零寬連字等複雜 Unicode 情況。
  • Lua 5.3+ 可考慮使用 utf8 標準庫 (utf8.len, utf8.offset) 簡化實作。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved