2016-01-18 21 views
1

給定一個System.Text.Encoding實例和一個字符串,如何以編程方式確定該字符串是否可以使用該編碼表示?如何確定一個字符串是否可以使用給定的編碼來表示

我正在編寫一個序列化庫,並且在編寫一個字符串時,我需要知道該字符串是否可以原樣寫入,或者是否需要轉義。

我看着Encoding的成員,但似乎沒有提供該信息。一種選擇可能是以某種方式創建一個等效實例Encoding,但是自定義EncoderFallback將捕獲它是否已被使用,然後嘗試使用編碼將字符串轉換爲字節。雖然這看起來有點不合理,效率也不高。

+0

雖然我明白你的問題,我沒有看到與序列化的關係,我不明白爲什麼你需要這些信息。希望有大量的系統將這些信息序列化爲字符串。 –

+0

儘管與序列化沒有嚴格關係,但我遇到的問題是輸出格式旨在爲人類可讀。因此,如果編碼支持它,我想直接寫文本。否則,格式支持轉義字符以ASCII碼編碼任何代碼點。 –

+0

您可以在這裏獲得其他字符集與Unicode之間的映射列表,例如:http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/。 (我還沒有運行任何具有多種編碼的非Unicode字符集。) –

回答

0

afaik,在c#中String始終是Unicode。在這種情況下,您可以遍歷字符串的每個字符,並檢查其數字值是否適合某種編碼。例如。具有0x1234的Unicode字符將不適合ASCII範圍0x00-0xFF(0x7F,準確)。

EDIT
ASCII:7(8)位。 「第8位」字符是代碼頁相關的,這意味着相同的數值在不同的代碼頁中看起來會顯示爲不同的字符。沒有機會改變這一點,afaik。
UTF7:應該是非常罕見的,根據維基百科它不是標準的一部分。
UTF8:8位,與上半場的ASCII碼相同。
UTF16,32:16 resp。 32位。
Afaik,字符0x1234在UTF16和32中是相同的,但UTF8當然不存在。
不幸的是,我不知道任何方式來找出給定的字符0xAB是以ASCII(以及在哪個代碼頁)或UTF8給出的。其實,我懷疑有沒有辦法...

+0

當然,但我怎麼知道在給定的編碼中哪些值是有效的?如果它是ASCII,那很容易,但我不知道我會得到哪個奇怪的編碼。 –

+0

關於ISO-8859-1和其他我甚至不知道的編碼呢?我無法控制我將收到哪些編碼。 –

+0

「c#中的字符串始終是Unicode」:是的,語言規範從一開始就說明了這一點。 (不要害怕C#規範;根據需要很容易讀取部分。) –

0

我解決了這個問題,通過編碼字符串,解碼它,然後與原來的比較。這看起來非常低效。

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

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

var textCanBeRepresentedByTargetEncoding = decodedText.Equals(text); 
+0

如果你是在性能之後,我肯定會使用UTFxx和Unicode都可以,並且所有SingleByte都不是(這代表了.NET中所有實際定義的編碼)的事實,並且使用這個算法作爲編碼的最後手段,完全適合這兩個類別(或派生類)。 –

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 
相關問題