2012-11-05 4 views
7

C'è un modo per estrarre la prima lettera di una stringa codificata UTF-8 con Lua?Estrarre la prima lettera di una stringa UTF-8 con Lua

Lua non supporta correttamente Unicode, quindi string.sub("ÆØÅ", 2, 2) restituirà "?" anziché "Ø".

Esiste un algoritmo di analisi UTF-8 relativamente semplice che potrei utilizzare sul byte di stringa per byte, al solo scopo di ottenere la prima lettera della stringa, sia essa un carattere cinese o una A?

O è troppo complesso, che richiede una grande biblioteca, ecc?

+0

"* semplice algoritmo di analisi Unicode *" Che * tipo * di "Unicode" è questo? È UTF-8, UTF-16, qualcos'altro? Qual è la codifica? –

+2

http://www.joelonsoftware.com/articles/Unicode.html Leggi questo. Per favore. – Cubic

+1

Ecco anche una [pagina per utenti Lua] (http://lua-users.org/wiki/LuaUnicode) –

risposta

16

Si può facilmente estrarre la prima lettera di una stringa codificata UTF-8 con il seguente codice:

function firstLetter(str) 
    return str:match("[%z\1-\127\194-\244][\128-\191]*") 
end 

Poiché un punto di codice UTF-8 sia inizia con un byte da 0 a 127, o con un byte da 194 a 244 seguito da uno o più byte da 128 a 191.

È anche possibile iterate sopra UTF-8 punti di codice in una maniera simile:

for code in str:gmatch("[%z\1-\127\194-\244][\128-\191]*") do 
    print(code) 
end 

noti che entrambi gli esempi restituiscono un valorestringa per ogni lettera, e non il punto di codice Unicode valore numerico.

+0

Brillante! Questa era esattamente la risposta che stavo cercando. Breve e preciso. – forthrin

+0

Questo è ragionevole per i dati che sono già stati convalidati, ma si potrebbe voler fare attenzione con i dati che non sono stati. – bames53

2

Lua 5.3 fornire un UTF-8 library.

È possibile utilizzare utf8.codes per ottenere ogni punto di codice, e quindi utilizzare utf8.char per ottenere il carattere:

local str = "ÆØÅ" 
for _, c in utf8.codes(str) do 
    print(utf8.char(c)) 
end 

Questo funziona anche:

local str = "ÆØÅ" 
for w in str:gmatch(utf8.charpattern) do 
    print(w) 
end 

dove utf8.charpattern è solo la stringa "[\0-\x7F\xC2-\xF4][\x80-\xBF]*" affinché il modello corrisponda a una sequenza di byte UTF-8.