You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Lua中如何判断string.sub处理俄语双字节字符得到的未知符号?

解决Lua中UTF-8字符截取后的匹配问题

Lua标准库的string.sub是按字节处理的,俄语“слово”这类UTF-8字符每个占2字节,string.sub("слово", 1,1)取到的是第一个字符的第一个字节(十六进制为0xD1)。这个单独的字节属于无效UTF-8序列,终端会显示成�,但变量a实际存储的是这个单字节值,所以直接匹配�、?这些显示符号肯定没用。

直接匹配的正确写法

你可以直接匹配这个字节的实际值,两种方式都可以:

  • 用十六进制转义字符:
    if a == "\xD1" then
        -- 匹配成功后的逻辑
    end
    
  • 用string.char转换ASCII码:
    if a == string.char(0xD1) then
        -- 匹配成功后的逻辑
    end
    

更靠谱的长期方案

如果经常要处理UTF-8字符串,建议用支持UTF-8的专用库(比如LuaUTF8),或者自己实现按字符截取的函数,避免出现这种半截字节的问题。比如这个简单的UTF-8字符截取函数:

function utf8_get_char(str, index)
    local pos = 1
    local char_count = 0
    while pos <= #str do
        char_count = char_count + 1
        if char_count == index then
            local byte = string.byte(str, pos)
            local char_len = 1
            if byte >= 0xC0 and byte <= 0xDF then char_len = 2
            elseif byte >= 0xE0 and byte <= 0xEF then char_len = 3
            elseif byte >= 0xF0 and byte <= 0xF7 then char_len = 4 end
            return string.sub(str, pos, pos + char_len - 1)
        end
        -- 跳过当前字符的所有字节
        local byte = string.byte(str, pos)
        if byte < 0x80 then pos = pos + 1
        elseif byte < 0xE0 then pos = pos + 2
        elseif byte < 0xF0 then pos = pos + 3
        else pos = pos + 4 end
    end
    return ""
end

-- 使用示例
local a = utf8_get_char("слово", 1)
print(a) -- 输出正确的"с"
if a == "с" then
    print("匹配成功")
end

内容的提问来源于stack exchange,提问作者Consler

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 23:37:14