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

我正在重写一个awk程序,用于格式化要输出到状态栏的字符串。我不是程序员,只是在利用业余时间学习。

当截取任何非ASCII字符,例如西里尔字母(utf8),结果会显示为一系列问号,显示出损坏的输出。

Ouverture Il Ritorno dall'Estero op. 89 / Mendelsshon / Великие �… / 320 kb/s

string.len#计算的是字节数而不是字符数。而单个西里尔字母的计数为2个字节而不是1个字节。这显然会使截断复杂化。幸运的是,Lua 5.3包含了一个utf8库unicode支持的wiki,用于简化处理非ascii字符。我修改了"shorten"函数,使用utf8.len来获取准确的字符数以进行截断,但问题仍然存在。

--来自penlight库,使用utf8.len,而不是string.len
function shorten(s,w)
    local ellipsis = "…"
    local n_ellipsis = utf8.len(ellipsis)
    assert_string(1,s)
    if utf8.len(s) > w then
        return s:sub(1,w-n_ellipsis) .. ellipsis
    end
    return s
end

进一步阅读后,我学到了要使用utf8.offset来实现所需的字节索引。

您应该在任何需要处理您自己没有编写或可能包含非ASCII或非英文字符的文本的地方使用这些函数。如果在非码点之间截取字符串的字节索引,您将得到一个无效的UTF-8字符串,可能会呈现不正确或无法存储在DataStore中。

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

我一直在努力弄清如何使用utf8.offset来获取所需的字节索引,但迄今为止,一无所获。如果需要更多上下文,请查看我的不成熟的完整脚本

任何提示,代码,批评等都会受到欢迎。

点赞
用户9077076
用户9077076

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

返回 s:sub(1, utf8.offset(s, w - n_ellipsis + 1) - 1) .. ellipsis
2019-09-10 01:23:53