2012-11-05 10 views
7

Gibt es eine Möglichkeit, den ersten Buchstaben einer UTF-8-codierten Zeichenfolge mit Lua zu extrahieren?Extrahieren Sie den ersten Buchstaben einer UTF-8-Zeichenfolge mit Lua

Lua unterstützt Unicode nicht ordnungsgemäß, daher gibt string.sub("ÆØÅ", 2, 2) anstelle von "Ø" zurück.

Gibt es einen relativ einfachen UTF-8-Parsing-Algorithmus, den ich für das String-Byte pro Byte verwenden könnte, um den ersten Buchstaben der Zeichenfolge zu erhalten, sei es ein chinesisches Zeichen oder ein A?

Oder ist dieser Weg zu komplex, erfordert eine große Bibliothek usw.?

+0

"* einfacher Unicode-Parsing-Algorithmus *" Was * Art * von "Unicode" ist das? Ist es UTF-8, UTF-16, etwas anderes? Was ist die Codierung? –

+2

http://www.joelonsoftware.com/articles/Unicode.html Lesen Sie dies. Bitte. – Cubic

+1

Hier ist auch eine [Seite für Lua Benutzer] (http://lua-users.org/wiki/LuaUnicode) –

Antwort

16

Sie können die ersten Buchstaben aus einem UTF-8 kodierten String mit dem folgenden Code leicht extrahieren:

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

Da ein UTF-8-Punkt-Code entweder mit einem Byte von 0 bis 127 beginnen, oder mit einem Byte von 194 durch ein oder mehrere Bytes von 128 bis 191. gefolgt 244

Sie können sogar Iterierte über UTF-8-Codepunkte in ähnlicher Weise:

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

Beachten Sie, dass beide Beispiele einen String Wert für jeden Buchstaben und nicht den numerischen Wert des Unicode-Codepunkts zurückgeben.

+0

Brilliant! Das war genau die Antwort, nach der ich suchte. Kurz und präzise. – forthrin

+0

Dies ist sinnvoll für Daten, die bereits validiert wurden, aber Sie sollten vorsichtig mit Daten sein, die nicht bereits geprüft wurden. – bames53

2

Lua 5.3 bieten eine UTF-8 library.

Sie können utf8.codes verwenden, um jeden Codepunkt zu bekommen, und dann utf8.char verwenden, um die Zeichen zu erhalten:

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

Dies funktioniert auch:

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

wo utf8.charpattern nur die Zeichenfolge "[\0-\x7F\xC2-\xF4][\x80-\xBF]*", damit das Muster mit einer UTF-8-Bytefolge übereinstimmt.

Verwandte Themen