我想用ASCII字符表示特殊字符,如CR, LF, NULL等。
基本上,我想写一个包含这些特殊字符的字符串变量到ASCII日志文本文件中,这样我就可以从这个文件中复制文本,然后粘贴到visual studio中,以接收同样的字符串变量。
我想最好的方法是用visual studio代码编辑器使用的格式来写特殊字符。(请赐教字符串格式是如何调用的)。
示例代码。
string mystring = "\r\n\0\0\u0001\u0018\0\0\u0001\u000fXML";
Console.WriteLine(mystring);
所以我想把... mystring
以致于 Console.WriteLine
将输出 \r\n\0\0\u0001\u0018\0\0\u0001\u000fXML
而不是。
Console只是一个简单的方法来描述这个问题. 我将以不同的方式打印我的字符串,所以我需要将 mystring 转换为一个字符串,以打印 \r\n\0\0\u0001\u0018\0\0\u0001\u000fXML
(和所有其他特殊字符以同样的方式)。
这些字符被称为 逃逸序列. 你可以咨询 文法 来查看字符串文字中哪些字符需要转义。 基本上你可以用Unicode字符转义序列转义任何字符。
\u
hex_digit hex_digit hex_digit hex_digit hex_digit hex_digit
例如:将U+000D改为 \u000d
为回车字符。
如果你想保持字符串简短,那么有一些 不要 需要逃离。 那些... 做 需要逃逸的是。
"
(U+0022)\
(U+005C)其他的都可以按字面意思插入。
如果你只想对你的源文件进行ASCII编码,那么你可以对哪些字符进行更严格的限制。 你可能会想要非常严格的限制。
给自己做一个函数来决定一个字符是否应该被转义。 你可能想从这样的函数开始。
public static bool IsSafeForLiteral(char ch) =>
ch < 127
&& ch != '\u0022' // double quote
&& ch != '\u005c' // backslash
&& ch != '\u000d' // carriage return
&& ch != '\u000a' // line feed
&& (
Char.IsLetterOrDigit(ch)
|| Char.IsPunctuation(ch)
|| Char.IsSymbol(ch)
|| (ch == ' ')
);
然后用这个测试来构造一个函数 把一个字符串变成C#源代码的字符串文字。
public static string ToSourceStringLiteral(string str)
{
StringBuilder sb = new StringBuilder();
sb.Append("\"");
foreach (char c in str) {
if (IsSafeForLiteral(c)) {
sb.Append(c);
} else {
sb.AppendFormat(@"\u{0:X4}", (int)c);
}
}
sb.Append("\"");
return sb.ToString();
}
如果你真的很喜欢回车的想法,那么你就可以把它当作 \r
而不是 \u000d
那么你就必须进一步对所有这些转义序列进行编程。
一种方法是制作一个替换字符的字典,并应用它。
public static Dictionary<char, string> CSharpSpecialEscapes = new Dictionary<char, string>() {
{ '\u0000', @"\0" },
{ '\u0007', @"\a" },
{ '\u0008', @"\b" },
{ '\u0009', @"\t" },
{ '\u000a', @"\n" },
{ '\u000b', @"\v" },
{ '\u000c', @"\f" },
{ '\u000d', @"\r" },
{ '\u001b', @"\e" },
{ '\u005c', @"\\" }
};
public static string ToSourceStringLiteral(this string str)
{
StringBuilder sb = new StringBuilder();
sb.Append("\"");
foreach (char c in str) {
if (CSharpSpecialEscapes.TryGetValue(c, out string replacement)) {
sb.Append(replacement);
} else if (IsSafeForLiteral(c)) {
sb.Append(c);
} else {
sb.AppendFormat(@"\u{0:X4}", (int)c);
}
}
sb.Append("\"");
return sb.ToString();
}
根据性能要求,你也可以用0...127范围内的所有替换字符预先填充一个数组,然后使用这个数组,尽管这时源码开始看起来不那么可维护了。 我推荐我上面写的东西,因为它是描述性的(与字符串转义序列的定义方式很匹配,而不是最佳效率)。
我还让这个版本在开头和结尾添加了引号。 你可以很容易地删除那些说 sb.Append("\"");
如果你不想要它们。
您可以在引号前使用"@"符号。
string mystring = @"\r\n\0\0\u0001\u0018\0\0\u0001\u000fXML";
这可以防止用反斜杠转义 \
编辑。
或者直接用双反斜杠来逃避反斜杠本身。
string mystring = "\\r\\n\\0\\0\\u0001\\u0018\\0\\0\\u0001\\u000fXML";