如何检查数字编码实体是否是有效的 ISO8859-1 编码?

How to check whether a numeric encoded entity is a valid ISO8859-1 encoding?

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

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

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

使用 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 包括所有 printable 字符,所以如果你只想知道一个字符是否有定义的字形,你可以使用前者。然而,如今大多数人倾向于表示 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
    }

这确实效率低下,但对所有 Charset 都有效。

如果你为 ISO_8859_1 尝试这个,你会发现它可以编码所有 8 位值,即 0–255。所以它显然使用了完整的 ISO-8859-1 定义。