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

时间:2016-01-18 17:19:04

标签: c# .net character-encoding

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

我正在编写一个序列化库,在编写字符串时,我需要知道该字符串是否可以按原样写入,还是需要进行转义。

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

3 个答案:

答案 0 :(得分:0)

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

修改
ASCII:7(8)位。 “第8位”字符与代码页相关,这意味着相同的数字值在不同的代码页中看起来会显示为不同的字符。没有机会改变它,afaik UTF7:应该是非常罕见的,根据维基百科,它不是标准的一部分 UTF8:8位,与上半部分的ASCII相同 UTF16,32:16 resp。 32位。
Afaik,字符0x1234在UTF16和32中是相同的,但当然在UTF8中不存在。
不幸的是,我不知道是否有任何方法可以确定给定的字符0xAB是以ASCII(以及代码页)还是UTF8给出的。实际上,我怀疑有一种方法......

答案 1 :(得分:0)

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

Encoding targetEncoding = Encoding.GetEncoding(28595);
var text = "Гранит";

var encodedBytes = targetEncoding.GetBytes(text);
var decodedText = targetEncoding.GetString(encodedBytes);

var textCanBeRepresentedByTargetEncoding = decodedText.Equals(text);

答案 2 :(得分:0)

我真的不喜欢使用控件流的异常,但这个解决方案的简单性肯定比创建自定义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