lua,截断包含utf-8编码字符的字符串

lua,截断包含utf-8编码字符的字符串,utf-8,lua,truncate,Utf 8,Lua,Truncate,我正在重写一个awk程序,该程序格式化要输出到状态栏的字符串。我不是一个程序员,只是一个业余爱好者,试图在任何休息时间学习 截断任何非ASCII字符时,例如西里尔字母(utf8)会导致输出损坏,显示为一系列问号 Ouverture Il Ritorno dall'Estero作品89/Mendelsshon/С砦砦砦砦砦砦�… / 320 kb/s string.len和#计数字节,而不是字符。一个西里尔字符被计算为2字节而不是1字节。这显然会使截断复杂化。Lua5.3包含了一个用于简化非a

我正在重写一个awk程序,该程序格式化要输出到状态栏的字符串。我不是一个程序员,只是一个业余爱好者,试图在任何休息时间学习

截断任何非ASCII字符时,例如西里尔字母(utf8)会导致输出损坏,显示为一系列问号

Ouverture Il Ritorno dall'Estero作品89/Mendelsshon/С砦砦砦砦砦砦�…  /  320 kb/s

string.len
#
计数字节,而不是字符。一个西里尔字符被计算为2字节而不是1字节。这显然会使截断复杂化。Lua5.3包含了一个用于简化非acsii字符处理的。我修改了“shorten”函数以使用
utf8.len
,以获得用于截断的准确字符数,但问题仍然存在

--从penlight库中,使用utf8.len,而不是string.len
功能缩短(s、w)
局部省略号=“…”
局部n_省略号=utf8.len(省略号)
断言字符串(1,s)
如果utf8.len(s)>w,则
返回s:sub(1,w-n_省略)。。省略
结束
返回s
结束
通过进一步阅读,我了解到utf8.offset应该在需要截断时使用

您应该在需要处理非自己编写的文本或可能包含非ASCII或非英语字符的文本的任何位置使用这些函数。如果在不在整个代码点之间的字节索引处截断字符串,则最终将得到无效的UTF-8字符串,该字符串可能呈现不正确或无法存储在数据存储中

如果要在索引处截断字符串,则应使用string.sub和utf8.offset给出的字节索引

我一直在试图找出如何使用
utf8.offset
获得所需的字节索引,但迄今为止没有成功。如果进一步的上下文有帮助,下面是我的wip

任何提示、代码、批评等都将不胜感激

感谢您提供的解决方案。在Lua 5.3中:

return s:sub(1, utf8.offset(s, w - n_ellipsis + 1) - 1) .. ellipsis

返回s:sub(1,utf8.偏移量(s,w-n_省略号+1)-1)。。省略号
非常感谢@EgorSkriptunoff。这确实解决了问题:)也比我预期的要简单一些。正确。请从问题中删除您的解决方案,并将其作为答案发布。