Подтвердить что ты не робот

.NET заменяет непечатаемый ASCII строковым представлением шестнадцатеричного кода

У меня есть строка с некоторыми непечатаемыми символами ascii, например:

"ABCD\x09\x05\r\n"

Я хочу заменить эти символы строковым представлением шестнадцатеричных кодов ascii, поэтому я получаю что-то вроде этого:

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

Каков наилучший способ сделать это? Можно ли использовать регулярное выражение?

4b9b3361

Ответ 1

Образец \p{Cc} соответствует любому управляющему символу, поэтому

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

также заменит управляющие символы.

Ответ 2

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, но это более понятно, и, вероятно, это не так важно, если это не критично.

Ответ 3

Вдохновленный примером Джейсона, но немного проще. Я не уверен, что работает лучше, и у меня нет времени тестировать его прямо сейчас, но он должен делать все за один проход:

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()));

Я тестировал это для функциональности.