Длина арабских букв в 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. Итак, подумайте, какие из этих мер вам нужны.