首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用多个ASCII字符表示特殊字符

如何使用多个ASCII字符表示特殊字符
EN

Stack Overflow用户
提问于 2020-05-12 20:49:09
回答 2查看 397关注 0票数 0

我正在尝试使用相应的多字符ASCII表示来表示特殊字符,如CR、LF、NULL等\r\n\0。

基本上,我希望将包含这些特殊字符的字符串变量写入到ASCII日志文本文件中,这样我就可以从该文件中复制文本,将其粘贴到visual studio中,以接收所写入的相同字符串变量。

我认为最好的方法是以visual studio代码编辑器使用的相同格式编写特殊字符。(请告诉我字符串格式的调用方式)。

示例代码:

代码语言:javascript
运行
复制
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 (以及所有其他特殊字符)的字符串。

EN

回答 2

Stack Overflow用户

发布于 2020-05-12 21:55:24

这些被称为转义序列。您可以参考the grammar来查看字符串文字中需要转义的字符。基本上,您可以使用任何字符的Unicode字符转义序列对其进行转义。

\u hex_digit hex_digit

例如:将回车字符的U+000D替换为\u000d

如果你想保持字符串简短,那么有一些不能转义的字符串需要转义。do需要转义的是:

  • " (U+0022)
  • \ (U+005C)
  • Carriage回车字符(U+000D)
  • Line换行字符(U+000A)
  • Next行字符(U+0085)
  • Line分隔符字符(U+2028)
  • Paragraph分隔符字符(U+2029)

其他一切都可以按字面插入。

此外,如果只想允许源文件的ASCII编码,那么您可以对字面上表示的字符进行更多的限制。您可能需要非常严格的限制。

让你自己成为一个决定字符是否应该转义的函数。您可能希望从如下所示的函数开始:

代码语言:javascript
运行
复制
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#源代码。

代码语言:javascript
运行
复制
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的形式出现的,那么你还必须编写所有这些转义序列。

一种方法是制作一个替换字符的字典,并将其应用于此。

代码语言:javascript
运行
复制
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("\"");的行。

票数 1
EN

Stack Overflow用户

发布于 2020-05-12 20:53:04

您可以在引号前使用"@“符号。

代码语言:javascript
运行
复制
string mystring = @"\r\n\0\0\u0001\u0018\0\0\u0001\u000fXML";

这样可以防止使用反斜杠\进行转义

编辑:

或者直接使用双反斜杠来转义反斜杠本身。

代码语言:javascript
运行
复制
string mystring = "\\r\\n\\0\\0\\u0001\\u0018\\0\\0\\u0001\\u000fXML";
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61752159

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档