【问题标题】:Decode a single character from octets in lisp从 lisp 中的八位字节解码单个字符
【发布时间】:2015-10-17 16:34:26
【问题描述】:

如何从普通 lisp 中的八位字节向量中解码单个字符?

我想要类似的东西:

(decode-character vector :start i :encoding :utf-8)

或更具体地:

(decode-character #(195 164 195 173 99 195 176) :start 0)
=> #\LATIN_SMALL_LETTER_A_WITH_DIAERESIS

这将返回从vector 中的i 位置开始的UTF-8 编码字符。

我不知道如何使用 babel 或 flexi-streams 来做到这一点。

【问题讨论】:

  • 你可以看看trivial-utf-8
  • @coredump trivial-utf-8 没有我要的,只支持 utf-8 编码。

标签: string unicode lisp common-lisp


【解决方案1】:
(defun decode-character (vector &rest args)
  (char (apply #'babel:octets-to-string
               (coerce vector '(vector (unsigned-byte 8))) args)
        0))

【讨论】:

  • 之前我不会coerce,而是check-type
  • encoding 关键字参数似乎与问题相关。
  • 如果它使用@coredump 的答案中的 start 和 end 关键字参数,这将起作用。我希望得到一些不会不必要地创建字符串的东西,但这至少有效。
  • @Thayne 如果您需要在较低级别工作,您还可以查看 octets-to-string 是如何实现的。也许引入一个从流中获取下一个字符的自定义read-character 函数并不难实现。
【解决方案2】:

这可能不是您想要的(如果可以的话,我很乐意更新)。 我没有看 Babel,但你可以概括我猜其他编码的方法。我会在这里坚持trivial-utf-8。我会这样做:

(defun decode-utf-8-char (octet-vector &key (start 0))
  (char (trivial-utf-8:utf-8-bytes-to-string 
          octet-vector
          :start start
          :end (+ start 4)) 0))

使用示例向量给出您想要的结果。 它起作用的原因是因为 utf-8 字符最多为4 bytes long。对char 的调用是为了获取第一个字符,以防实际读取多个字符。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-01-10
    • 1970-01-01
    • 1970-01-01
    • 2010-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多