2011-08-12 16 views
12

我有它的一些非打印的ASCII字符的字符串,像非打印的ASCII:.NET替換的十六進制代碼字符串表示

"ABCD\x09\x05\r\n" 

我想用一個ASCII字符串替換這些字符十六進制代碼數字的表示,所以我得到的是這樣的:

"ABCD[09][05][0D][0A]" 

最新最好的方式做到這一點?是否可以使用正則表達式?

回答

23

\p{Cc}任何控制字符相匹配的圖案,所以

Regex.Replace(input, 
       @"\p{Cc}", 
       a=>string.Format("[{0:X2}]", (byte)a.Value[0]) 
      ); 

也將取代控制字符。

+0

不錯。簡單易用。 – user380689

+0

請注意,您不能輕易地將此返回到原始消息中作爲「ABCD [09] \ x09 \ x05 \ r \ n」會導致「ABCD [09] [09] [05] [0D] [0A] 」。你想逃避左大括號(通常使用「[[」,這樣我的示例將變成「ABCD [[09] [09] [05] [0D] [0A]」 –

8
string s = "ABCD\x09\x05\r\n"; 
var replace = 
    s.Select(c => Char.IsControl(c) ? ((int)c).ToString("X2") : c.ToString()) 
    .Aggregate(new StringBuilder(), (sb, t) => sb.Append(t)) 
    .ToString(); 

對不起,沒有編譯器方便,但我認爲這編譯和完成這項工作。

此外,這種走字符串兩次(一次投影每個字符到一個十六進制替換或一個字符串,然後再次聚合),你可以通過將投影放到Enumerable.Aggregate的調用中來避免這種情況,但這更清楚,除非性能至關重要,否則它可能並不重要。

+0

Aghh。打我幾分鐘。確認通過LINQPad工作。 –

+1

啊,謝謝,我不想看看不清楚的版本。 –

+0

+1;很棒的示例代碼。現在我已經找到了一個找到'Aggregate'用法的立足點:)爲了便於閱讀,我個人將select函數推入本地代理。 –

4

受Jason的例子啓發,但有點簡單。我不知道哪個性能更好,並且沒有時間去基準它的權利,但它應該只在一個通所做的一切:

string s = "ABCD\x09\x05\r\n"; 
string replace = String.Concat(s.Select(c => Char.IsControl(c) ? 
              String.Format("[{0:X2}]", (int)c) : 
              c.ToString())); 

我測試過本作的功能。

相關問題