UTF-8 and Unicode
string.upper/lower only handle ASCII (locale-dependent). For full Unicode case mapping, normalization, and graphemes, use libraries like luautf8 (lua-utf8) or ICU bindings.
Lua 5.1/LuaJIT have no utf8 library. Use the luautf8 rock or a compat module.
-- Lua strings are byte sequences. The utf8 library (5.3+) handles UTF-8.
local s = "héllo wörld ❤"
print(#s) --> byte count (more than the character count)
print(utf8.len(s)) --> character (code point) count
for pos, code in utf8.codes(s) do
io.write(utf8.char(code), "(", code, ") ")
end
print()
print(utf8.char(72, 233, 10084)) --> Hé❤
print(utf8.codepoint(s, 1, -1)) -- all code points
print(utf8.offset(s, 3)) --> byte position of the 3rd character
print(s:sub(utf8.offset(s, 2), utf8.offset(s, 3) - 1)) --> é (substring by characters)
print(utf8.charpattern) --> pattern matching one UTF-8 character
for ch in s:gmatch(utf8.charpattern) do io.write("[", ch, "]") end
print(utf8.len("\xff")) --> nil 1 (invalid byte position)