Длина арабских букв в Lua
В языке Lua, когда я хочу получить длину одной арабской буквы (например, "ف"
), ответ будет 2
!
Исх.
local letter = "ف"
print( letter:len() )
Выход: 2
Такая же проблема возникает, когда я использую (string.sub(a,b))
. Если я хочу напечатать первую букву арабского слова, я не могу сказать (string.sub(1,1)
.
Ex.
local word_1 = "فولت"
print( word_1:sub(1,2) )
Выход: ف
как вы видели, я вернул второй аргумент (2), а не (1), чтобы получить правильный ответ.
если я поставлю первый аргумент 1, ответ будет следующим:
print( word_1:sub(1,1) )
Выход: Ù
Почему Lua подсчитывает длину одной арабской буквы как две?
И есть ли способ получить нужную длину, которая равна 1?
Ответы
Ответ 1
Lua имеет 8-битную чистоту.
Другими словами, строка Lua представляет собой последовательность байтов, она не поддерживает Unicode внутренне. Арабская буква "ف"
имеет 2 байта, поэтому Lua рассматривает ее как строку длиной 2.
Вам нужно использовать специальный трюк для управления Unicode, например, если предполагается использование UTF-8, вы можете использовать этот фрагмент для подсчета длины строки (Referece: Lua Unicode):
local _, count = string.gsub(unicode_string, "[^\128-\193]", "")
Ответ 2
Lua 5.3 теперь выпущен. Он предоставляет базовую библиотеку UTF-8.
utf8.len
можно использовать для получения длины строки UTF-8:
print(utf8.len("ف"))
-- 1
Ответ 3
Lua, будучи 8-битным чистым, достаточно, чтобы сказать, что Lua поддерживает Unicode. Хотя без дополнительной библиотеки поддержки юникода размер поддержки минимален.
Для любой строки Unicode существует не менее 4 способов ее измерения: единицы кода, кодовые точки, кластеры Grapheme. Четвертым способом является bytecount, который является постоянным кратным единицам кода, в зависимости от того, какой UTF используется. UTF-8: 1 UTF16: 2 UTF32: 4.
Итак, подумайте, какие из этих мер вам нужны.