当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《我可以将C#字符串值转换为转义字符串文字》经验,为你挑选了9个好方法。

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

如果这段代码:

Console.WriteLine(someString);

生产:

Hello
World!

我想要这个代码:

Console.WriteLine(ToLiteral(someString));

生产:

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

Hallgrim.. 169

我找到了这个:

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!"

很好,但请注意,对于更长的字符串,这将插入"+"运算符,换行符和缩进.我找不到办法把它关掉. (14认同)

有没有办法让它逐字输出("@"......"`)文字? (4认同)


小智.. 32

什么Regex.Escape(字符串)?

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

这不是OP所要求的.它不返回字符串文字,它返回一个带有Regex特殊字符转义的字符串.这会把"Hello World?"变成"Hello World \?",但这是一个无效的字符串文字. (33认同)

+1不知道为什么会这样.其他答案太冗长,看起来像重新发明轮子 (5认同)

+1即使它没有完全回答OP的问题,但当我遇到这个问题时,我(我怀疑也许是其他人)正在寻找.:) (5认同)


Cristi Diaco.. 23

编辑:一种更结构化的方法,包括strings和chars的所有转义序列.
不会将unicode字符替换为其等效字符.也不煮鸡蛋.

public class ReplaceString
{
    static readonly IDictionary m_replaceDict 
        = new Dictionary();

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

    }
}


ICR.. 18

public static class StringHelpers
{
    private static Dictionary escapeMapping = new Dictionary()
    {
        {"\"", @"\\\"""},
        {"\\\\", @"\\"},
        {"\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)];
    }
}


Arsen Zahray.. 16

尝试:

var t = HttpUtility.JavaScriptStringEncode(s);

@Paul您想要的与问题所提出的相反。根据您的描述,这可以回答问题,因此可以完成工作。 (2认同)


小智.. 15

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;
        }
    }
}


Smilediver.. 14

完全工作的实现,包括转义Unicode和ASCII不可打印字符.不插入像Hallgrim的回答那样的"+"符号.

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

您应该使用`Char.GetUnicodeCategory(c)== UnicodeCategory.Control`来决定是否要逃避它,或者不会说ASCII的人不会很开心. (2认同)


Nelson Reis.. 8

有趣的问题.

如果找不到更好的方法,可以随时更换.
如果您选择它,您可以使用此C#转义序列表:

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

\" - 双引号,字符串文字所需

\ - 反斜杠

\ 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#常见问题解答 中找到可用的字符转义序列?



1> Hallgrim..:

我找到了这个:

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!"


很好,但请注意,对于更长的字符串,这将插入"+"运算符,换行符和缩进.我找不到办法把它关掉.
有没有办法让它逐字输出("@"......"`)文字?

2> 小智..:

什么Regex.Escape(字符串)?

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


这不是OP所要求的.它不返回字符串文字,它返回一个带有Regex特殊字符转义的字符串.这会把"Hello World?"变成"Hello World \?",但这是一个无效的字符串文字.
+1不知道为什么会这样.其他答案太冗长,看起来像重新发明轮子
+1即使它没有完全回答OP的问题,但当我遇到这个问题时,我(我怀疑也许是其他人)正在寻找.:)

3> Cristi Diaco..:

编辑:一种更结构化的方法,包括strings和chars的所有转义序列.
不会将unicode字符替换为其等效字符.也不煮鸡蛋.

public class ReplaceString
{
    static readonly IDictionary m_replaceDict 
        = new Dictionary();

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

    }
}



4> ICR..:
public static class StringHelpers
{
    private static Dictionary escapeMapping = new Dictionary()
    {
        {"\"", @"\\\"""},
        {"\\\\", @"\\"},
        {"\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)];
    }
}



5> Arsen Zahray..:

尝试:

var t = HttpUtility.JavaScriptStringEncode(s);


@Paul您想要的与问题所提出的相反。根据您的描述,这可以回答问题,因此可以完成工作。

6> 小智..:

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;
        }
    }
}



7> Smilediver..:

完全工作的实现,包括转义Unicode和ASCII不可打印字符.不插入像Hallgrim的回答那样的"+"符号.

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


您应该使用`Char.GetUnicodeCategory(c)== UnicodeCategory.Control`来决定是否要逃避它,或者不会说ASCII的人不会很开心.

8> Nelson Reis..:

有趣的问题.

如果找不到更好的方法,可以随时更换.
如果您选择它,您可以使用此C#转义序列表:

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

\" - 双引号,字符串文字所需

\ - 反斜杠

\ 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#常见问题解答 中找到可用的字符转义序列?


此链接不再有效,这是一个教科书示例,说明为什么不支持仅链接答案.

9> deerchao..:

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

推荐阅读
殉情放开那只小兔子
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有