如何确定是否可以使用给定编码表示字符串
本文关键字:编码表示 字符串 何确定 是否 可以使 | 更新日期: 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 给出的。实际上,我怀疑根本没有办法...