如何确定是否可以使用给定编码表示字符串

本文关键字:编码表示 字符串 何确定 是否 可以使 | 更新日期: 2023-09-27 18:30:47

给定一个System.Text.Encoding实例和一个字符串,如何以编程方式确定该字符串是否可以使用该编码表示?

我正在开发一个序列化库,在编写字符串时,我需要知道字符串是否可以按原样编写,或者是否需要转义。

我调查了Encoding的成员,但似乎没有人提供这些信息。一种选择可能是以某种方式创建 Encoding 的等效实例,但使用自定义EncoderFallback来捕获它是否已被使用,然后尝试使用编码将字符串转换为字节。不过,这似乎有点笨拙,效率不高。

如何确定是否可以使用给定编码表示字符串

我不太喜欢对控制流使用异常,但这个解决方案的简单性绝对胜过创建自定义EncoderFallback

public static bool CanBeEncoded(int codepage, string s)
{
    try
    {
        Encoding.GetEncoding(codepage,
                             EncoderFallback.ExceptionFallback,
                             DecoderFallback.ExceptionFallback).GetBytes(s);
        return true;
    }
    catch (EncoderFallbackException)
    {
        return false;
    }
}

用法:

Console.WriteLine(CanBeEncoded(1252, "Grüß Gott!")); // Prints True
Console.WriteLine(CanBeEncoded(1252, "Привет"));     // Prints False

我通过对字符串进行编码,对其进行解码,然后将其与原始字符串进行比较来解决此问题。不过,这似乎效率非常低。

Encoding targetEncoding = Encoding.GetEncoding(28595);
var text = "Гранит";
var encodedBytes = targetEncoding.GetBytes(text);
var decodedText = targetEncoding.GetString(encodedBytes);
var textCanBeRepresentedByTargetEncoding = decodedText.Equals(text);

Afaik,c# 中的String始终是 Unicode。在这种情况下,您可以循环访问字符串的每个字符,并检查其数值是否适合某种编码。例如,带有 0x1234 的 unicode 字符不适合 ASCII 范围 0x00-0xFF(准确地说是0x7F)。

编辑
ASCII : 7 (8) 位。"第 8 位"字符依赖于代码页,这意味着相同的数值在不同的代码页中显示为不同的字符。没有机会改变这一点,阿法克。
UTF7:应该非常罕见,根据维基百科,它不是标准的一部分。
UTF8:8位,与前半部分的ASCII相同。
UTF16,32:16 位或 32 位。
Afaik,字符0x1234在 UTF16 和 32 中是相同的,但在 UTF8 中当然不存在。
不幸的是,我不知道有任何方法可以找出给定的字符0xAB是以 ASCII(以及哪个代码页)还是 UTF8 给出的。实际上,我怀疑根本没有办法...