2012-11-26 17 views
7

Ich habe eine Zeichenfolge, die ich an eine externe Druckfunktion senden.
Ich muss die Zeichenfolge mit Backslashs auffüllen, damit es richtig druckt.Wie diese Zeichenfolge richtig zu entkommen ist

Insbesondere, ich brauche eine Methode, die in diesem Beispiel Eingabe akzeptieren würde:
This is a string\nwith a line break\ta tab\rand a carriage return.

und Ausgang:
This is a string\\nwith a line break\\ta tab\\rand a carriage return.

Muss ich mit es backslashed Ersatzkraft Replace alle möglichen Fluchtzeichen Brute brauchen?

Versuchen:
s.Replace("\\","\\\\") funktioniert nicht, weil es wörtlichen für einen umgekehrten Schrägstrich sucht.

s.Replace("\n","\\n") funktioniert natürlich, aber was ich suche ist eine generische Methode.

Bearbeiten: Bitte schlagen Sie keine Brute-Force-Methoden, ich verstehe, es ist kein Problem, eine solche Methode zu implementieren. Meine Frage war, ob es einen universelleren Ansatz gibt.

+0

Ihre Eingabe ist nicht klar - meinst du, dass Sie "eine Zeichenfolge mit einem Newline" in "eine Zeichenfolge mit einem umgekehrten Schrägstrich gefolgt von einem n" konvertieren möchten? –

+0

@Jon Ja, genau. Ich muss meine Schnur darauf vorbereiten, dass sie doppelt entkommen kann. – Rotem

+0

@Rotem Was ist mit @ "Dies ist eine Zeichenfolge \ nmit einem Zeilenumbruch"? Einen schönen Tag :) –

Antwort

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

nimmt Eingang "\tHello\r\n\tLiterals!" und verwandelt es in "\\tHello\\r\\n\\tLiterals!"

Works für jede Eingabe - es wird Sie die Escape-Sequenz für etwas zu bekommen.

+1

Bravo, danke! Erwähnenswert ist auch, dass die Klassen in den Namensräumen 'System.CodeDom' und' System.CodeDom.Compiler' existieren. – Rotem

+0

Schön, aber beachten Sie, dass bei längeren Strings "+" Operatoren, Zeilenumbrüche und Einrückungen eingefügt werden. Ich konnte keinen Weg finden, das abzuschalten. – Timwi

0

können Sie mehr ersetzt verwenden, um das mit auslesbaren Steuer Zeichen der Whitespaces erzwingen ersetzen:

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

jedoch nicht die Schrägstriche so einfach verdoppeln, wie Sie denken, weil die Zeichen bereits im Speicher umgewandelt werden seine binären Werte. Sie müssen also jedes Zeichen von Hand ersetzen.

+1

Ich sagte ausdrücklich, dass ich weiß, dass dies funktioniert und dass ich nach einer Methode suche, die sich um alle Kontrollzeichen kümmert. – Rotem

+0

Sie könnten auch weitere Regeln hinzufügen ... – rekire

+0

Ich habe das Beispiel aktualisiert, wenn es klarer wird. – Rotem

4

Hier ist die Funktion, die ich dafür verwende. Ich habe dies seit Jahren im Produktionscode verwendet und es scheint sich gegen alle möglichen Fälle zu behaupten.

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

Das würde ich den Brute-Force-Ansatz nennen, der in der Frage erwähnt wurde - und trotzdem für die Notierung von Unit-Testfällen aufgewertet: P – Markus

Verwandte Themen