首页 文章

我可以将C#字符串值转换为转义字符串文字

提问于
浏览
171

在C#中,我可以将字符串值转换为字符串文字,我会在代码中看到它吗?我想用它们的转义序列替换制表符,换行符等 .

如果这段代码:

Console.WriteLine(someString);

生产环境 :

Hello
World!

我想要这个代码:

Console.WriteLine(ToLiteral(someString));

生产环境 :

\tHello\r\n\tWorld!\r\n

15 回答

  • 12

    我找到了这个:

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

    这段代码:

    var input = "\tHello\r\n\tWorld!";
    Console.WriteLine(input);
    Console.WriteLine(ToLiteral(input));
    

    生产环境 :

    Hello
        World!
    "\tHello\r\n\tWorld!"
    
  • 23

    Regex.Escape(String)怎么样?

    Regex.Escape通过用它们的转义码替换它们来转义一组最小字符(\,*,,?,|,{,[,(,),^,$ ,.,#和空格) .

  • 6

    编辑:一种更结构化的方法,包括 stringchar 的所有转义序列 .
    也没有煮鸡蛋 .

    public class ReplaceString
    {
        static readonly IDictionary<string, string> m_replaceDict 
            = new Dictionary<string, string>();
    
        const string ms_regexEscapes = @"[\a\b\f\n\r\t\v\\""]";
    
        public static string StringLiteral(string i_string)
        {
            return Regex.Replace(i_string, ms_regexEscapes, match);
        }
    
        public static string CharLiteral(char c)
        {
            return c == '\'' ? @"'\''" : string.Format("'{0}'", c);
        }
    
        private static string match(Match m)
        {
            string match = m.ToString();
            if (m_replaceDict.ContainsKey(match))
            {
                return m_replaceDict[match];
            }
    
            throw new NotSupportedException();
        }
    
        static ReplaceString()
        {
            m_replaceDict.Add("\a", @"\a");
            m_replaceDict.Add("\b", @"\b");
            m_replaceDict.Add("\f", @"\f");
            m_replaceDict.Add("\n", @"\n");
            m_replaceDict.Add("\r", @"\r");
            m_replaceDict.Add("\t", @"\t");
            m_replaceDict.Add("\v", @"\v");
    
            m_replaceDict.Add("\\", @"\\");
            m_replaceDict.Add("\0", @"\0");
    
            //The SO parser gets fooled by the verbatim version 
            //of the string to replace - @"\"""
            //so use the 'regular' version
            m_replaceDict.Add("\"", "\\\""); 
        }
    
        static void Main(string[] args){
    
            string s = "here's a \"\n\tstring\" to test";
            Console.WriteLine(ReplaceString.StringLiteral(s));
            Console.WriteLine(ReplaceString.CharLiteral('c'));
            Console.WriteLine(ReplaceString.CharLiteral('\''));
    
        }
    }
    
  • 28
    public static class StringHelpers
    {
        private static Dictionary<string, string> escapeMapping = new Dictionary<string, string>()
        {
            {"\"", @"\\\"""},
            {"\\\\", @"\\"},
            {"\a", @"\a"},
            {"\b", @"\b"},
            {"\f", @"\f"},
            {"\n", @"\n"},
            {"\r", @"\r"},
            {"\t", @"\t"},
            {"\v", @"\v"},
            {"\0", @"\0"},
        };
    
        private static Regex escapeRegex = new Regex(string.Join("|", escapeMapping.Keys.ToArray()));
    
        public static string Escape(this string s)
        {
            return escapeRegex.Replace(s, EscapeMatchEval);
        }
    
        private static string EscapeMatchEval(Match m)
        {
            if (escapeMapping.ContainsKey(m.Value))
            {
                return escapeMapping[m.Value];
            }
            return escapeMapping[Regex.Escape(m.Value)];
        }
    }
    
  • 13

    尝试:

    var t = HttpUtility.JavaScriptStringEncode(s);
    
  • 8

    Hallgrim的答案非常好,但“”,换行符和缩进添加功能对我来说是破坏功能的 . 一个简单的方法是:

    private static string ToLiteral(string input)
    {
        using (var writer = new StringWriter())
        {
            using (var provider = CodeDomProvider.CreateProvider("CSharp"))
            {
                provider.GenerateCodeFromExpression(new CodePrimitiveExpression(input), writer, new CodeGeneratorOptions {IndentString = "\t"});
                var literal = writer.ToString();
                literal = literal.Replace(string.Format("\" +{0}\t\"", Environment.NewLine), "");
                return literal;
            }
        }
    }
    
  • 1

    Hallgrim的回答很棒 . 如果您需要使用c#正则表达式解析其他空格字符和换行符,这是一个小调整 . 我需要这个在序列化的Json值的情况下插入谷歌表,并在代码插入标签,空格等时遇到麻烦 .

    provider.GenerateCodeFromExpression(new CodePrimitiveExpression(input), writer, null);
      var literal = writer.ToString();
      var r2 = new Regex(@"\"" \+.\n[\s]+\""", RegexOptions.ECMAScript);
      literal = r2.Replace(literal, "");
      return literal;
    
  • 18

    完全工作的实现,包括转义Unicode和ASCII不可打印字符 . 不插入像Hallgrim's answer这样的"+"标志 .

    static string ToLiteral(string input) {
            StringBuilder literal = new StringBuilder(input.Length + 2);
            literal.Append("\"");
            foreach (var c in input) {
                switch (c) {
                    case '\'': literal.Append(@"\'"); break;
                    case '\"': literal.Append("\\\""); break;
                    case '\\': literal.Append(@"\\"); break;
                    case '\0': literal.Append(@"\0"); break;
                    case '\a': literal.Append(@"\a"); break;
                    case '\b': literal.Append(@"\b"); break;
                    case '\f': literal.Append(@"\f"); break;
                    case '\n': literal.Append(@"\n"); break;
                    case '\r': literal.Append(@"\r"); break;
                    case '\t': literal.Append(@"\t"); break;
                    case '\v': literal.Append(@"\v"); break;
                    default:
                        // ASCII printable character
                        if (c >= 0x20 && c <= 0x7e) {
                            literal.Append(c);
                        // As UTF16 escaped character
                        } else {
                            literal.Append(@"\u");
                            literal.Append(((int)c).ToString("x4"));
                        }
                        break;
                }
            }
            literal.Append("\"");
            return literal.ToString();
        }
    
  • 0

    有趣的问题 .

    如果找不到更好的方法,可以随时更换 .
    如果你选择它,你可以使用这个 C# Escape Sequence List

    • ' - 单引号,字符文字所需

    • \“ - 双引号,字符串文字需要

    • \ - 反斜杠

    • \ 0 - Unicode字符0

    • \ a - 警报(字符7)

    • \ b - 退格(字符8)

    • \ f - 换页(字符12)

    • \ n - 新行(字符10)

    • \ r - 回车(字符13)

    • \ t - 水平制表符(字符9)

    • \ v - 垂直引号(字符11)

    • \ uxxxx - 十六进制值为xxxx的字符的Unicode转义序列

    • \ xn [n] [n] [n] - 具有十六进制值nnnn的字符的Unicode转义序列(\ uxxxx的可变长度版本)

    • \ Uxxxxxxxx - 具有十六进制值xxxxxxxx的字符的Unicode转义序列(用于生成代理)

    这个列表可以在C#常见问题中找到What character escape sequences are available?

  • -7

    对于Smilediver的答案,这是一个小小的改进,它不会逃避所有的非ASCII字符,但只有这些才真正需要 .

    using System;
    using System.Globalization;
    using System.Text;
    
    public static class CodeHelper
    {
        public static string ToLiteral(this string input)
        {
            var literal = new StringBuilder(input.Length + 2);
            literal.Append("\"");
            foreach (var c in input)
            {
                switch (c)
                {
                    case '\'': literal.Append(@"\'"); break;
                    case '\"': literal.Append("\\\""); break;
                    case '\\': literal.Append(@"\\"); break;
                    case '\0': literal.Append(@"\0"); break;
                    case '\a': literal.Append(@"\a"); break;
                    case '\b': literal.Append(@"\b"); break;
                    case '\f': literal.Append(@"\f"); break;
                    case '\n': literal.Append(@"\n"); break;
                    case '\r': literal.Append(@"\r"); break;
                    case '\t': literal.Append(@"\t"); break;
                    case '\v': literal.Append(@"\v"); break;
                    default:
                        if (Char.GetUnicodeCategory(c) != UnicodeCategory.Control)
                        {
                            literal.Append(c);
                        }
                        else
                        {
                            literal.Append(@"\u");
                            literal.Append(((ushort)c).ToString("x4"));
                        }
                        break;
                }
            }
            literal.Append("\"");
            return literal.ToString();
        }
    }
    
  • 0
    public static class StringEscape
    {
      static char[] toEscape = "\0\x1\x2\x3\x4\x5\x6\a\b\t\n\v\f\r\xe\xf\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\"\\".ToCharArray();
      static string[] literals = @"\0,\x0001,\x0002,\x0003,\x0004,\x0005,\x0006,\a,\b,\t,\n,\v,\f,\r,\x000e,\x000f,\x0010,\x0011,\x0012,\x0013,\x0014,\x0015,\x0016,\x0017,\x0018,\x0019,\x001a,\x001b,\x001c,\x001d,\x001e,\x001f".Split(new char[] { ',' });
    
      public static string Escape(this string input)
      {
        int i = input.IndexOfAny(toEscape);
        if (i < 0) return input;
    
        var sb = new System.Text.StringBuilder(input.Length + 5);
        int j = 0;
        do
        {
          sb.Append(input, j, i - j);
          var c = input[i];
          if (c < 0x20) sb.Append(literals[c]); else sb.Append(@"\").Append(c);
        } while ((i = input.IndexOfAny(toEscape, j = ++i)) > 0);
    
        return sb.Append(input, j, input.Length - j).ToString();
      }
    }
    
  • 159

    我将ToVerbatim添加到 Hallgrim's 的尝试接受了以上答案:

    private static string ToLiteral(string input)
    {
        using (var writer = new StringWriter())
        {
            using (var provider = CodeDomProvider.CreateProvider("CSharp"))
            {
                provider.GenerateCodeFromExpression(new CodePrimitiveExpression(input), writer, new CodeGeneratorOptions { IndentString = "\t" });
                var literal = writer.ToString();
                literal = literal.Replace(string.Format("\" +{0}\t\"", Environment.NewLine), "");           
                return literal;
            }
        }
    }
    
    private static string ToVerbatim( string input )
    {
        string literal = ToLiteral( input );
        string verbatim = "@" + literal.Replace( @"\r\n", Environment.NewLine );
        return verbatim;
    }
    
  • 1

    如果JSON约定对于你想要转义的非转义字符串是足够的,并且你已经在项目中使用了 Newtonsoft.Json (它有相当大的开销),你可以像下面这样使用这个包:

    using System;
    using Newtonsoft.Json;
    
    public class Program
    {
        public static void Main()
        {
        Console.WriteLine(ToLiteral( @"abc\n123") );
        }
    
        private static string ToLiteral(string input){
            return JsonConvert.DeserializeObject<string>("\"" + input + "\"");
        }
    }
    
  • 14

    我提交了自己的实现,它处理 null 值,并且由于使用了数组查找表,手动十六进制转换和避免 switch 语句而应该更高效 .

    using System;
    using System.Text;
    using System.Linq;
    
    public static class StringLiteralEncoding {
      private static readonly char[] HEX_DIGIT_LOWER = "0123456789abcdef".ToCharArray();
      private static readonly char[] LITERALENCODE_ESCAPE_CHARS;
    
      static StringLiteralEncoding() {
        // Per http://msdn.microsoft.com/en-us/library/h21280bw.aspx
        var escapes = new string[] { "\aa", "\bb", "\ff", "\nn", "\rr", "\tt", "\vv", "\"\"", "\\\\", "??", "\00" };
        LITERALENCODE_ESCAPE_CHARS = new char[escapes.Max(e => e[0]) + 1];
        foreach(var escape in escapes)
          LITERALENCODE_ESCAPE_CHARS[escape[0]] = escape[1];
      }
    
      /// <summary>
      /// Convert the string to the equivalent C# string literal, enclosing the string in double quotes and inserting
      /// escape sequences as necessary.
      /// </summary>
      /// <param name="s">The string to be converted to a C# string literal.</param>
      /// <returns><paramref name="s"/> represented as a C# string literal.</returns>
      public static string Encode(string s) {
        if(null == s) return "null";
    
        var sb = new StringBuilder(s.Length + 2).Append('"');
        for(var rp = 0; rp < s.Length; rp++) {
          var c = s[rp];
          if(c < LITERALENCODE_ESCAPE_CHARS.Length && '\0' != LITERALENCODE_ESCAPE_CHARS[c])
            sb.Append('\\').Append(LITERALENCODE_ESCAPE_CHARS[c]);
          else if('~' >= c && c >= ' ')
            sb.Append(c);
          else
            sb.Append(@"\x")
              .Append(HEX_DIGIT_LOWER[c >> 12 & 0x0F])
              .Append(HEX_DIGIT_LOWER[c >>  8 & 0x0F])
              .Append(HEX_DIGIT_LOWER[c >>  4 & 0x0F])
              .Append(HEX_DIGIT_LOWER[c       & 0x0F]);
        }
    
        return sb.Append('"').ToString();
      }
    }
    
  • -1

    Code:

    string someString1 = "\tHello\r\n\tWorld!\r\n";
    string someString2 = @"\tHello\r\n\tWorld!\r\n";
    
    Console.WriteLine(someString1);
    Console.WriteLine(someString2);
    

    Output:

    Hello
        World!
    
    \tHello\r\n\tWorld!\r\n
    

    这是你想要的吗?

相关问题