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
相关产品推荐
相关产品推荐

