6

外部の印刷関数に送信する文字列があります。
正しく印刷されるように、文字列をバックスラッシュで埋める必要があります。

具体的には、この入力例を受け入れるメソッドが必要です。
This is a string\nwith a line break\ta tab\rand a carriage return.

および出力:
This is a string\\nwith a line break\\ta tab\\rand a carriage return.

Replaceバックスラッシュに相当するすべての可能なエスケープ文字を総当たり攻撃する必要がありますか?

試しました:
s.Replace("\\","\\\\") バックスラッシュリテラルを探しているため、機能しません。

s.Replace("\n","\\n")明らかに機能しますが、私が探しているのは一般的な方法です。

編集: 力ずくの方法を提案しないでください、私はそのような方法を実装することは問題がないことを理解しています。私の質問は、もっと普遍的なアプローチがあるかどうかでした。

4

3 に答える 3

11
private static string EscapeLiterals(string input)
{
    using (var writer = new StringWriter())
    {
        using (var provider = CodeDomProvider.CreateProvider("CSharp"))
        {
            provider.GenerateCodeFromExpression(new CodePrimitiveExpression(input), writer, null);
            return writer.ToString();
        }
    }
}

入力"\tHello\r\n\tLiterals!"を受け取り、それを"\\tHello\\r\\n\\tLiterals!"

どんな入力でも機能します - どんな入力でもエスケープ シーケンスを取得できます。

于 2012-11-26T21:20:30.237 に答える
3

これが私がこれに使用する関数です。私はこれを本番コードで何年も使用してきましたが、あらゆる種類のコーナーケースに耐えられるようです。

/// <summary>
/// Escapes all characters in this string whose code is less than 32 using C/C#-compatible backslash escapes.
/// </summary>
public static string CLiteralEscape(this string value)
{
    if (value == null)
        throw new ArgumentNullException("value");

    var result = new StringBuilder(value.Length + value.Length / 2);

    for (int i = 0; i < value.Length; i++)
    {
        char c = value[i];
        switch (c)
        {
            case '\0': result.Append(@"\0"); break;
            case '\a': result.Append(@"\a"); break;
            case '\b': result.Append(@"\b"); break;
            case '\t': result.Append(@"\t"); break;
            case '\n': result.Append(@"\n"); break;
            case '\v': result.Append(@"\v"); break;
            case '\f': result.Append(@"\f"); break;
            case '\r': result.Append(@"\r"); break;
            case '\\': result.Append(@"\\"); break;
            case '"': result.Append(@"\"""); break;
            default:
                if (c >= ' ')
                    result.Append(c);
                else // the character is in the 0..31 range
                    result.AppendFormat(@"\x{0:X2}", (int) c);
                break;
        }
    }

    return result.ToString();
}
于 2012-11-29T06:23:41.563 に答える
0

複数の置換を使用して、空白を読み取り可能な制御文字に強制的に置き換えることができます。

s = s.Replace("\n", "\\n").Replace("\r", "\\r").Replace("\t", "\\t");

ただし、文字はすでにバイナリ値でメモリ内で変換されているため、バックスラッシュを思ったほど単純に2倍にすることはできません。したがって、すべての文字を手作業で置き換える必要があります。

于 2012-11-26T21:02:25.220 に答える