Сделать специальный символ C # - PullRequest
6 голосов
/ 05 июня 2019

У меня есть строка с специальными символами , как в этом примере: 12345678912 \ rJ \ u0011 , потому что мне нужно иметь доступ к этим специальным символам для настройки моего приложения.Я хочу отобразить эту строку точно так же, как это в поле TextBox, поэтому все, что я до сих пор пробовал, приводит к строке, где символ \u0011 пытается отобразить с пустым символом в конце: "7896104866061\rJ".

Я сделал это, но это не работает.

string result = Regex.Replace(
    ToLiteral(this.Buffer), 
   "[^\x00-\x7Fd]", 
    c => string.Format("\\u{0:x4}", (int)c.Value[0]))
 .Replace(@"\", @"\\");

public static string ToLiteral(string input)
    {
        using (var writer = new StringWriter())
        {
            using (var provider = CodeDomProvider.CreateProvider("CSharp"))
            {
                provider.GenerateCodeFromExpression(
                    new CodePrimitiveExpression(input), 
                    writer, 
                    null);

                return writer.ToString();
            }
        }
    }

Что мне нужно сделать?Заранее спасибо.

Ответы [ 3 ]

2 голосов
/ 05 июня 2019

Вот мой фрагмент для отображения символов Ctrl: https://gist.github.com/TheTrigger/6efa6a8e42eedf1e61e0db8e9ef4360a

using System.Text;

namespace CtrlCharReplace
{
    public static class Extensions
    {
        public static string ReplaceCtrl(this string s)
        {
            var sb = new StringBuilder();
            for (int i = 0; i < s.Length; i++)
            {
                char c = s[i];

                var isCtrl = char.IsControl(c);
                var n = char.ConvertToUtf32(s, i);

                if (isCtrl)
                {
                    sb.Append($"\\u{n:X4}");
                }
                else
                {
                    sb.Append(c);
                }
            }

            return sb.ToString();
        }
    }
}
1 голос
/ 05 июня 2019

Давайте построить строку в цикле ;у нас есть несколько категорий символов:

  1. Известные элементы управления, такие как \n, \t, \r
  2. Элементы управления, такие как \u0011
  3. Символы, которые должныбыть экранированным: " и \
  4. Простые символы, которые следует указывать в виде

Код:

using System.Linq;
...

private static IReadOnlyDictionary<char, string> s_KnownControls = new 
  Dictionary<char, string>() {
    { '\0', "\\0"},
    { '\a', "\\a"},
    { '\b', "\\b"},
    { '\n', "\\n"},
    { '\v', "\\v"},
    { '\t', "\\t"},
    { '\f', "\\f"},
    { '\r', "\\r"},
  };

public static string ToLiteral(string input) {
  if (null == input)
    return null;

  StringBuilder sb = new StringBuilder();

  foreach (var c in input) {
    if (char.IsControl(c))
      sb.Append(s_KnownControls.TryGetValue(c, out var s) 
        ? s 
        : $"\\u{((int)c):x4}");
    else {
      if (c == '"' || c == '\\') // escapement 
        sb.Append('\\'); 

      sb.Append(c);
    } 
  }

  return sb.ToString();  
}

Демо:

  string[] tests = new string[] {
    "12345678912\rJ\u0011",
    "abc\tdef\t\0A\n\a\bB",
    "abc\"def\"xyz\\pqr"
  };

  string report = string.Join(Environment.NewLine, tests
    .Select(test => ToLiteral(test)));

Результат:

12345678912\rJ\u0011
abc\tdef\t\0A\n\a\bB
abc\"def\"xyz\\pqr
1 голос
/ 05 июня 2019

Сделайте замену \ на \\ перед вызовом ToLiteral, и вы получите желаемый результат.

string result = Regex.Replace(ToLiteral("12345678912\\rJ\\u0011".Replace(@"\", @"\\")), "[^\x00-\x7Fd]", c => string.Format("\\u{0:x4}", (int)c.Value[0]));
...