it-swarm.com.de

Kann ich einen C # -Stringwert in ein Escape-Stringliteral konvertieren?

Kann ich in C # einen String-Wert in ein String-Literal konvertieren, wie ich es im Code sehen würde? Ich möchte Tabulatoren, Zeilenumbrüche usw. durch ihre Escape-Sequenzen ersetzen.

Wenn dieser Code:

Console.WriteLine(someString);

produziert:

Hello
World!

Ich möchte diesen Code:

Console.WriteLine(ToLiteral(someString));

produzieren:

\tHello\r\n\tWorld!\r\n
170
Hallgrim

Ich habe das gefunden:

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();
        }
    }
}

Dieser Code:

var input = "\tHello\r\n\tWorld!";
Console.WriteLine(input);
Console.WriteLine(ToLiteral(input));

Produziert:

    Hello
    World!
"\tHello\r\n\tWorld!"
158
Hallgrim

Was ist mit Regex.Escape (String) ?

Regex.Escape entgeht einer minimalen Menge von Zeichen (\, *, +,?, |, {, [ (,), ^, $,., # Und Leerzeichen), indem sie durch ihre Escapezeichen ersetzt werden Codes.

26
Shqdooow

EDIT: Ein strukturierterer Ansatz einschließlich aller Escape-Sequenzen für strings und chars. 
Ersetzt die Unicode-Zeichen nicht durch das wörtliche Äquivalent . Sie kocht auch keine Eier.

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('\''));

    }
}
23
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)];
    }
}
17
ICR

versuchen:

var t = HttpUtility.JavaScriptStringEncode(s);
14
Arsen Zahray

Hallgrims Antwort ist hervorragend, aber die Zusätze "+", "Newline" und "Einzug" waren für mich die Funktionalität. Ein einfacher Weg dahin ist:

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;
        }
    }
}
12
lesur

Voll funktionsfähige Implementierung, einschließlich der Umgehung von Unicode-Zeichen und ASCII nicht druckbaren Zeichen Fügt keine "+" - Zeichen ein wie Hallgrims Antwort .

    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();
    }
11
Smilediver

Interessante Frage.

Wenn Sie keine bessere Methode finden, können Sie sie immer ersetzen.
Wenn Sie sich dafür entscheiden, können Sie diese C # Escape-Sequenzliste verwenden:

  • \ '- einfaches Anführungszeichen für Zeichenliterale
  • \ "- doppeltes Anführungszeichen, erforderlich für Stringliterale
  • \ - Backslash
  • \ 0 - Unicode-Zeichen 0
  • \ a - Warnung (Zeichen 7)
  • \ b - Rücktaste (Zeichen 8)
  • \ f - Formularvorschub (Zeichen 12)
  • \ n - Neue Zeile (Zeichen 10)
  • \ r - Wagenrücklauf (Zeichen 13)
  • \ t - Registerkarte "Horizontal" (Zeichen 9)
  • \ v - Vertikales Anführungszeichen (Zeichen 11)
  • \ uxxxx - Unicode-Escape-Sequenz für Zeichen mit Hex-Wert xxxx
  • \ xn [n] [n] [n] - Unicode-Escape-Sequenz für Zeichen mit Hex-Wert nnnn (Version mit variabler Länge von\uxxxx)
  • \ Uxxxxxxxx - Unicode-Escape-Sequenz für Zeichen mit Hex-Wert xxxxxxxx (zur Erzeugung von Ersatzzeichen) 

Diese Liste finden Sie in den häufig gestellten Fragen zu C # Welche Escape-Sequenzen gibt es?

8
Nelson Reis

Hier ist eine kleine Verbesserung für Smiledivers Antwort, es wird nicht allen Nicht-ASCII-Zeichen entkommen, aber nur diese werden wirklich benötigt.

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();
    }
}
4
deerchao
public static class StringEscape
{
  static char[] toEscape = "\0\x1\x2\x3\x4\x5\x6\a\b\t\n\v\f\r\xe\xf\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\"\\".ToCharArray();
  static string[] literals = @"\0,\x0001,\x0002,\x0003,\x0004,\x0005,\x0006,\a,\b,\t,\n,\v,\f,\r,\x000e,\x000f,\x0010,\x0011,\x0012,\x0013,\x0014,\x0015,\x0016,\x0017,\x0018,\x0019,\x001a,\x001b,\x001c,\x001d,\x001e,\x001f".Split(new char[] { ',' });

  public static string Escape(this string input)
  {
    int i = input.IndexOfAny(toEscape);
    if (i < 0) return input;

    var sb = new System.Text.StringBuilder(input.Length + 5);
    int j = 0;
    do
    {
      sb.Append(input, j, i - j);
      var c = input[i];
      if (c < 0x20) sb.Append(literals[c]); else sb.Append(@"\").Append(c);
    } while ((i = input.IndexOfAny(toEscape, j = ++i)) > 0);

    return sb.Append(input, j, input.Length - j).ToString();
  }
}
1
Serge N

Mein Versuch, ToVerbatim zu Hallgrims akzeptierter Antwort hinzuzufügen:

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;
        }
    }
}

private static string ToVerbatim( string input )
{
    string literal = ToLiteral( input );
    string verbatim = "@" + literal.Replace( @"\r\n", Environment.NewLine );
    return verbatim;
}
1
Derek

Hallgrims Antwort war ausgezeichnet. Hier ist ein kleiner Tweak für den Fall, dass Sie zusätzliche Leerzeichen und Zeilenumbrüche mit einem regulären c # -Ausdruck analysieren müssen. Ich brauchte dies im Fall eines serialisierten Json-Werts für das Einfügen in Google Sheets und bekam Probleme, da der Code Tabs, +, Leerzeichen usw. einfügte. 

  provider.GenerateCodeFromExpression(new CodePrimitiveExpression(input), writer, null);
  var literal = writer.ToString();
  var r2 = new Regex(@"\"" \+.\n[\s]+\""", RegexOptions.ECMAScript);
  literal = r2.Replace(literal, "");
  return literal;
0
Alexander Yoshi

Wenn JSON-Konventionen für die nicht maskierten Zeichenfolgen ausreichen, für die eine Escape-Aktion ausgeführt werden soll, und Sie bereits Newtonsoft.Jsonin Ihrem Projekt verwenden (dies hat einen ziemlich großen Aufwand), können Sie dieses Paket folgendermaßen verwenden:

using System;
using Newtonsoft.Json;

public class Program
{
    public static void Main()
    {
    Console.WriteLine(ToLiteral( @"abc\n123") );
    }

    private static string ToLiteral(string input){
        return JsonConvert.DeserializeObject<string>("\"" + input + "\"");
    }
}
0
ehsan88