【问题标题】:How to check whether a numeric encoded entity is a valid ISO8859-1 encoding?如何检查数字编码实体是否是有效的 ISO8859-1 编码?
【发布时间】:2021-11-23 07:30:20
【问题描述】:

假设我得到了随机字符引用,例如 〹。我需要一个解决方案来检查这是否是有效的编码。

我想我可以使用 Charset 库,但我无法完全确定如何提出解决方案。

【问题讨论】:

    标签: html kotlin character-encoding


    【解决方案1】:

    [此答案已在进一步研究后重写。]

    使用Charsets 没有简单的答案;复杂的见下文。

    使用字符代码有一些简单的答案,但事实证明这完全取决于您所说的 ISO8859-1 的含义!

    根据the Wikipedia page on ISO/IEC 8859-1,字符集ISO8859-1只定义了字符32-126和160-255。所以你可以简单地检查这些范围,例如:

    fun Char.isISO8859_1() = this.toInt() in 32..126 || this.toInt() in 160..255
    

    但是,同一页面还提到了字符集 ISO-8859-1(注意额外的连字符),它定义了所有 8 位字符 (0–255),将控制字符分配给额外的字符。你可以检查 that 例如:

    fun Char.isISO_8859_1() = this.toInt() in 0..255
    

    ISO8859-1 包括所有可打印 字符,因此如果您只想知道一个字符是否具有已定义的字形,则可以使用前者。然而,现在大多数人倾向于表示ISO-8859-1:这是许多网页使用的(那些还没有转向 UTF-8 的网页),这就是前 256 个 Unicode 字符的定义。所以后者可能会更普遍有用。

    上述两种方法当然都非常简短、简单、高效;但它们只适用于一个字符集;当库类已经具有该信息时,它是字符集的尴尬硬编码细节。

    Charset 对象似乎主要针对编码和解码,因此它们没有提供简单的方法来判断哪些字符是这样定义的。但是您可以找出它们是否可以对给定字符进行编码。这是我找到的最简单的方法:

    fun Char.isIn(charset: Charset) =
        try {
            charset.newEncoder()
                   .onUnmappableCharacter(CodingErrorAction.REPORT)
                   .encode(CharBuffer.wrap(toString()))
            true
        } catch (x: CharacterCodingException) {
            false
        }
    

    这确实效率低下,但适用于所有Charsets。

    如果您尝试对ISO_8859_1 执行此操作,您会发现它可以编码所有 8 位值,即 0–255。所以它显然使用了完整的ISO-8859-1 定义。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-01-24
      • 2015-01-22
      • 2014-05-30
      • 1970-01-01
      • 2016-12-17
      • 2017-08-23
      • 1970-01-01
      相关资源
      最近更新 更多