【问题标题】:lua, truncate string containing utf-8 encoded charslua,截断包含 utf-8 编码字符的字符串
【发布时间】:2019-09-09 17:20:39
【问题描述】:

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

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

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

string.len# 计数字节,而不是字符。并且单个西里尔字符被计为 2 个字节而不是 1 个。这显然会使截断复杂化。幸运的是,Lua 5.3 包含 utf8 librarywiki on unicode support 以简化非 acsii 字符的使用。我修改了“缩短”功能以使用 utf8.len 以获得准确的 character 截断计数,但问题仍然存在。

--from penlight library, use utf8.len, not 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 中。

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

我一直在试图弄清楚如何使用utf8.offset 来获取所需的字节索引,但到目前为止成功率为零。如果进一步的上下文有帮助,这是我的 wip full script

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

【问题讨论】:

  • return s:sub(1, utf8.offset(s, w - n_ellipsis + 1) - 1) .. ellipsis
  • 非常感谢@EgorSkriptunoff。这确实解决了这个问题:) 也比我预期的要简单一些。马上。
  • 请从问题中删除您的解决方案并将其作为答案发布。

标签: utf-8 lua truncate


【解决方案1】:

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

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

【讨论】:

    猜你喜欢
    • 2011-08-16
    • 1970-01-01
    • 1970-01-01
    • 2014-06-09
    • 2013-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多