如何实现UTF-8转ISO-8859-2?多语言应用编码转换求助
Lua实现UTF-8到ISO-8859-2的编码转换
ISO-8859-1之所以好转,是因为它的字节值直接对应Unicode的U+0000到U+00FF码点,但ISO-8859-2(拉丁2)的字节映射是独立的,需要先把UTF-8解码为Unicode码点,再通过Unicode到ISO-8859-2的映射表完成转换。下面是具体实现步骤和代码:
核心思路
- 解码UTF-8字符串,得到每个字符的Unicode码点;
- 通过预定义的映射表,将Unicode码点转换为对应的ISO-8859-2字节值;
- 将所有字节拼接成最终的ISO-8859-2编码字符串;
- 对无法映射的字符(比如不在ISO-8859-2覆盖范围内的),做兜底处理(比如替换为
?)。
具体实现代码
第一步:UTF-8转Unicode码点
先实现一个通用的UTF-8解码函数,把字符串拆成单个Unicode码点:
local function utf8_to_unicode(s) local unicode = {} local i = 1 while i <= #s do local c = s:byte(i) local code if c < 0x80 then code = c i = i + 1 elseif c < 0xE0 then code = (c - 0xC0) * 0x40 + (s:byte(i+1) - 0x80) i = i + 2 elseif c < 0xF0 then code = (c - 0xE0) * 0x1000 + (s:byte(i+1) - 0x80) * 0x40 + (s:byte(i+2) - 0x80) i = i + 3 else -- 简化处理4字节UTF-8,不需要可忽略 code = (c - 0xF0) * 0x40000 + (s:byte(i+1) - 0x80) * 0x1000 + (s:byte(i+2) - 0x80) * 0x40 + (s:byte(i+3) - 0x80) i = i + 4 end table.insert(unicode, code) end return unicode end
第二步:构建Unicode到ISO-8859-2的映射表
ISO-8859-2的完整映射可从官方标准提取,下面列出波兰语、西班牙语等常用字符的映射,你可以按需补充完整:
local unicode_to_latin2 = { -- 波兰语常用字符 [0x0104] = 0xA1, -- Ą [0x0105] = 0xB9, -- ą [0x0106] = 0xA2, -- Ć [0x0107] = 0xE6, -- ć [0x0118] = 0xA3, -- Ę [0x0119] = 0xEA, -- ę [0x0141] = 0xA4, -- Ł [0x0142] = 0xB3, -- ł [0x0143] = 0xA5, -- Ń [0x0144] = 0xF1, -- ń [0x015A] = 0xA6, -- Ś [0x015B] = 0xBC, -- ś [0x0179] = 0xA7, -- Ż [0x017A] = 0xBF, -- ż [0x017B] = 0xA8, -- Ž [0x017C] = 0xEF, -- ž -- 西班牙语/葡萄牙语重叠字符(ISO-8859-2覆盖) [0x00C1] = 0xC1, -- Á [0x00E1] = 0xE1, -- á [0x00D3] = 0xD3, -- Ó [0x00F3] = 0xF3, -- ó } -- 补全ASCII范围的直接映射 for code = 0x00, 0x7F do unicode_to_latin2[code] = code end
第三步:实现完整的转换函数
将Unicode码点转换为ISO-8859-2字节,并拼接成字符串:
local function utf8_to_latin2(s) local unicode = utf8_to_unicode(s) local latin2_bytes = {} for _, code in ipairs(unicode) do local byte = unicode_to_latin2[code] if byte then table.insert(latin2_bytes, string.char(byte)) else -- 无法映射的字符,替换为? table.insert(latin2_bytes, "?") end end return table.concat(latin2_bytes) end
使用示例
local utf8_str = "Język polski, español, English" local latin2_str = utf8_to_latin2(utf8_str) print(latin2_str) -- 输出ISO-8859-2编码的字符串
注意事项
- 若需要完整的ISO-8859-2映射,可参考官方字符集标准,补充所有Unicode码点对应的字节值;
- 对于无法映射的字符,可根据业务需求调整兜底逻辑(比如保留原UTF-8或替换为特定符号);
- Lua 5.3+支持内置
utf8库,可用utf8.codepoint替代自定义解码函数,简化代码:-- 用内置库解码的简化版 local function utf8_to_unicode(s) local unicode = {} for _, code in utf8.codes(s) do table.insert(unicode, code) end return unicode end
内容的提问来源于stack exchange,提问作者Dragose
相关产品推荐
相关产品推荐

