Hal*_*rim 187 c# string escaping
在C#中,我可以将字符串值转换为字符串文字,我会在代码中看到它吗?我想用它们的转义序列替换制表符,换行符等.
如果这段代码:
Console.WriteLine(someString);
Run Code Online (Sandbox Code Playgroud)
生产:
Hello
World!
Run Code Online (Sandbox Code Playgroud)
我想要这个代码:
Console.WriteLine(ToLiteral(someString));
Run Code Online (Sandbox Code Playgroud)
生产:
\tHello\r\n\tWorld!\r\n
Run Code Online (Sandbox Code Playgroud)
Hal*_*rim 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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
这段代码:
var input = "\tHello\r\n\tWorld!";
Console.WriteLine(input);
Console.WriteLine(ToLiteral(input));
Run Code Online (Sandbox Code Playgroud)
生产:
Hello
World!
"\tHello\r\n\tWorld!"
Run Code Online (Sandbox Code Playgroud)
小智 32
Regex.Escape通过用它们的转义码替换它们来转义一组最小字符(\,*,+,?,|,{,[,(,),^,$ ,.,#和空格).
Cri*_*scu 23
编辑:一种更结构化的方法,包括string
s和char
s的所有转义序列.
不会将unicode字符替换为其等效字符.也不煮鸡蛋.
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('\''));
}
}
Run Code Online (Sandbox Code Playgroud)
ICR*_*ICR 18
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)];
}
}
Run Code Online (Sandbox Code Playgroud)
Ars*_*ray 16
尝试:
var t = HttpUtility.JavaScriptStringEncode(s);
Run Code Online (Sandbox Code Playgroud)
Gra*_*ham 16
NuGet 上Roslyn的Microsoft.CodeAnalysis.CSharp包中有一个方法:
private static string ToLiteral(string valueTextForCompiler)
{
return Microsoft.CodeAnalysis.CSharp.SymbolDisplay.FormatLiteral(valueTextForCompiler, false);
}
Run Code Online (Sandbox Code Playgroud)
显然,这在最初提出问题时并不存在,但它可能会对从 Google 搜索到这里的人有所帮助。
小智 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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
Smi*_*ver 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();
}
Run Code Online (Sandbox Code Playgroud)
有趣的问题.
如果找不到更好的方法,可以随时更换.
如果您选择它,您可以使用此C#转义序列表:
此列表可以在C#常见问题解答 中找到可用的字符转义序列?
这对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();
}
}
Run Code Online (Sandbox Code Playgroud)