我正在尝试使用相应的多字符ASCII表示来表示特殊字符,如CR、LF、NULL等\r\n\0。
基本上,我希望将包含这些特殊字符的字符串变量写入到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只是描述问题的一种简单方式。我将以不同的方式打印我的字符串,因此我需要将我的字符串转换为可以打印\r\n\0\0\u0001\u0018\0\0\u0001\u000fXML
(以及所有其他特殊字符)的字符串。
发布于 2020-05-12 21:55:24
这些被称为转义序列。您可以参考the grammar来查看字符串文字中需要转义的字符。基本上,您可以使用任何字符的Unicode字符转义序列对其进行转义。
\u
hex_digit hex_digit
例如:将回车字符的U+000D替换为\u000d
。
如果你想保持字符串简短,那么有一些不能转义的字符串需要转义。do需要转义的是:
"
(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("\"");
的行。
发布于 2020-05-12 20:53:04
您可以在引号前使用"@“符号。
string mystring = @"\r\n\0\0\u0001\u0018\0\0\u0001\u000fXML";
这样可以防止使用反斜杠\
进行转义
编辑:
或者直接使用双反斜杠来转义反斜杠本身。
string mystring = "\\r\\n\\0\\0\\u0001\\u0018\\0\\0\\u0001\\u000fXML";
https://stackoverflow.com/questions/61752159
复制相似问题