2013-09-09 6 views
6

У меня есть таблица, как этотКак преобразовать UTF8 массивы байтов в строку в Lua

table = {57,55,0,15,-25,139,130,-23,173,148,-24,136,158} 

это utf8 закодированные байт массива с помощью функции PHP распаковке

unpack('C*',$str); 

как я могу преобразовать его в UTF -8 строка, которую я могу прочитать в lua?

+0

Что эти цифры представляют? Предполагают ли они, что это коды, закодированные в utf-8, фактические числовые литералы, которые вы хотите преобразовать или что? – greatwolf

+0

это закодированный байтовый массив utf8 по функции распаковки php – Tony

ответ

5

Lua не предоставляет прямую функцию для преобразования таблицы utf-8 байтов в числовой форме в строковый литерал utf-8. Но это достаточно легко, чтобы написать что-то для этого с помощью string.char:

function utf8_from(t) 
    local bytearr = {} 
    for _, v in ipairs(t) do 
    local utf8byte = v < 0 and (0xff + v + 1) or v 
    table.insert(bytearr, string.char(utf8byte)) 
    end 
    return table.concat(bytearr) 
end 

Обратите внимание, что ни один из стандартных функций Lua или предоставить строковые объекты не являются UTF-8 известно. Если вы попробуете print закодированную строку utf-8, возвращенную из вышеуказанной функции, вы просто увидите некоторые фанковые символы. Если вам нужна более обширная поддержка utf-8, вы захотите проверить некоторые из библиотек, упомянутых в lua wiki.

+0

-1: не обрабатывает 3-х и 4-байтовые символы UTF8, такие как 'U + 20AC' -> € – Phrogz

2

Вот комплексное решение, которое работает для набора символов UTF-8, ограниченного RFC 3629:

do 
    local bytemarkers = { {0x7FF,192}, {0xFFFF,224}, {0x1FFFFF,240} } 
    function utf8(decimal) 
    if decimal<128 then return string.char(decimal) end 
    local charbytes = {} 
    for bytes,vals in ipairs(bytemarkers) do 
     if decimal<=vals[1] then 
     for b=bytes+1,2,-1 do 
      local mod = decimal%64 
      decimal = (decimal-mod)/64 
      charbytes[b] = string.char(128+mod) 
     end 
     charbytes[1] = string.char(vals[2]+decimal) 
     break 
     end 
    end 
    return table.concat(charbytes) 
    end 
end 

function utf8frompoints(...) 
    local chars,arg={},{...} 
    for i,n in ipairs(arg) do chars[i]=utf8(arg[i]) end 
    return table.concat(chars) 
end 

print(utf8frompoints(72, 233, 108, 108, 246, 32, 8364, 8212)) 
--> Héllö €— 
+0

Я только что заменил старую реализацию тем, что намного больше элегантный (не использует строки для бинарной математики), короче и, соответственно, примерно в 5 раз быстрее. – Phrogz

+0

Дополнительные оптимизации (отредактированные выше) обеспечивают еще 2 или более перфорации. – Phrogz