Lua字符串重音字符转标准字符异常问题求助
嘿,我来帮你排查这个u类重音字符转换失效的问题!你观察得很准——这段代码在普通Lua环境下正常工作,但在Tabletop Simulator(基于Unity)里对ù, ú, û, ü这类u系重音失效,输出空占位,确实大概率是Unity对Lua字符串编码处理的特殊Bug。
问题根源分析
你用的字符串匹配模式"([%z\1-\127\194-\244][\128-\191]*)"是用来捕获UTF-8多字节字符的,理论上u类重音的UTF-8编码(比如ù是0xC3 0xB9)完全在这个范围内,但Unity内嵌的Lua环境可能对这些字符的编码解析有差异,导致它们没有被正确匹配到tableAccents的键中,最终被当成未知字符处理了。
修复方案
针对这个特定环境的问题,我们可以换两种更稳妥的实现方式:
方案1:用UTF-8标准库遍历字符(推荐)
如果Tabletop Simulator的Lua版本支持utf8库(大部分现代Lua环境都支持),可以用utf8.codes和utf8.char来精准遍历每个UTF-8字符,彻底避免字节匹配的问题:
function stripChars(str) local tableAccents = { ["à"] = "a", ["á"] = "a", ["â"] = "a", ["ã"] = "a", ["ä"] = "a", ["ç"] = "c", ["è"] = "e", ["é"] = "e", ["ê"] = "e", ["ë"] = "e", ["ì"] = "i", ["í"] = "i", ["î"] = "i", ["ï"] = "i", ["ñ"] = "n", ["ò"] = "o", ["ó"] = "o", ["ô"] = "o", ["õ"] = "o", ["ö"] = "o", ["ù"] = "u", ["ú"] = "u", ["û"] = "u", ["ü"] = "u", ["ý"] = "y", ["ÿ"] = "y", ["À"] = "A", ["Á"] = "A", ["Â"] = "A", ["Ã"] = "A", ["Ä"] = "A", ["Ç"] = "C", ["È"] = "E", ["É"] = "E", ["Ê"] = "E", ["Ë"] = "E", ["Ì"] = "I", ["Í"] = "I", ["Î"] = "I", ["Ï"] = "I", ["Ñ"] = "N", ["Ò"] = "O", ["Ó"] = "O", ["Ô"] = "O", ["Õ"] = "O", ["Ö"] = "O", ["Ù"] = "U", ["Ú"] = "U", ["Û"] = "U", ["Ü"] = "U", ["Ý"] = "Y" } local normalizedString = '' -- 遍历每个UTF-8字符的编码点 for _, charCode in utf8.codes(str) do local utf8Char = utf8.char(charCode) -- 替换重音字符,否则保留原字符 normalizedString = normalizedString .. (tableAccents[utf8Char] or utf8Char) end return normalizedString end
方案2:直接精确匹配所有重音字符
如果UTF-8库不可用,我们可以把所有需要处理的重音字符直接列在匹配模式里,确保每个目标字符都被精准捕获:
function stripChars(str) local tableAccents = { -- 保持原有的映射表不变 ["à"] = "a", ["á"] = "a", ["â"] = "a", ["ã"] = "a", ["ä"] = "a", ["ç"] = "c", ["è"] = "e", ["é"] = "e", ["ê"] = "e", ["ë"] = "e", ["ì"] = "i", ["í"] = "i", ["î"] = "i", ["ï"] = "i", ["ñ"] = "n", ["ò"] = "o", ["ó"] = "o", ["ô"] = "o", ["õ"] = "o", ["ö"] = "o", ["ù"] = "u", ["ú"] = "u", ["û"] = "u", ["ü"] = "u", ["ý"] = "y", ["ÿ"] = "y", ["À"] = "A", ["Á"] = "A", ["Â"] = "A", ["Ã"] = "A", ["Ä"] = "A", ["Ç"] = "C", ["È"] = "E", ["É"] = "E", ["Ê"] = "E", ["Ë"] = "E", ["Ì"] = "I", ["Í"] = "I", ["Î"] = "I", ["Ï"] = "I", ["Ñ"] = "N", ["Ò"] = "O", ["Ó"] = "O", ["Ô"] = "O", ["Õ"] = "O", ["Ö"] = "O", ["Ù"] = "U", ["Ú"] = "U", ["Û"] = "U", ["Ü"] = "U", ["Ý"] = "Y" } local normalizedString = '' -- 匹配所有重音字符+ASCII字符 local pattern = "([àáâãäçèéêëìíîïñòóôõöùúûüýÿÀÁÂÃÄÇÈÉÊËÌÍÎÏÑÒÓÔÕÖÙÚÛÜÝ%z\1-\127])" for strChar in string.gmatch(str, pattern) do normalizedString = normalizedString .. (tableAccents[strChar] or strChar) end return normalizedString end
补充说明
你提到代码在Tabletop Simulator外运行正常,这进一步印证了是Unity内嵌Lua的字符串处理Bug——Unity有时会对字符串做隐式编码转换,导致部分字符的字节表示偏离标准UTF-8。上面的两种方案都能绕过这个问题,要么用标准UTF-8字符遍历,要么直接精确匹配目标字符。
另外,既然你已经标记问题解决,这段调整后的代码也能给其他遇到类似问题的模组开发者提供参考哦!
内容的提问来源于stack exchange,提问作者aJynks

