2013-03-06 11 views
15

Mein Problem:Entfernen von versteckten Zeichen aus Strings

Ich habe eine .NET-Anwendung, die Newsletter per E-Mail versendet. Wenn die Newsletters in Outlook angezeigt werden, zeigt Outlook anstelle eines ausgeblendeten Zeichens ein Fragezeichen an, das nicht erkannt werden kann. Diese versteckten Zeichen stammen von Endbenutzern, die html, die den Newsletter bilden, kopieren und in ein Formular einfügen und absenden. Ein C# trim() entfernt diese versteckten Zeichen, wenn sie am Ende oder Anfang der Zeichenfolge auftreten. Wenn der Newsletter in Google Mail angezeigt wird, kann Google Mail diese ignorieren. Wenn Sie diese versteckten Zeichen in ein Word-Dokument einfügen und die Option "Absatzmarken und verdeckte Symbole anzeigen" aktivieren, erscheinen die Symbole als ein Rechteck in einem größeren Rechteck. Auch der Text, aus dem die Newsletter bestehen, kann in jeder Sprache sein. Daher ist das Akzeptieren von Unicode-Zeichen ein Muss. Ich habe versucht, die Zeichenfolge durchzulaufen, um das Zeichen zu erkennen, aber die Schleife erkennt es nicht und überschreitet es. Auch den Endbenutzer zu bitten, den HTML-Code zuerst in den Notizblock einzufügen, bevor er ihn abschickt, kommt nicht in Frage.

Meine Frage:
Wie kann ich diese versteckten Zeichen mit C# erkennen und beseitigen?

+0

ein Beispiel Fügen Sie hier .. –

+0

Beispiel ungültige Werte wäre nett. Ich rate seine Unicode-Strings in ASCII-Text, aber auch das ist nur eine Vermutung. –

+0

regex, erlauben nur Buchstaben eine Zahl –

Antwort

42

Sie können alle Steuerzeichen aus dem Eingabestring mit etwas wie folgt entfernen:

string input; // this is your input string 
string output = new string(input.Where(c => !char.IsControl(c)).ToArray()); 

Here is the documentation für die IsControl() Methode.

Oder wenn Sie Buchstaben und Ziffern nur behalten möchten, können Sie auch die IsLetter und IsDigit Funktion:

string output = new string(input.Where(c => char.IsLetter(c) || char.IsDigit(c)).ToArray()); 
+0

Danke, ich werde das versuchen. Ich werde versuchen, es zu kodieren und es sofort wieder zu entschlüsseln, um zu sehen, ob das versteckte Zeichen entfernt ist. – bradley4

+0

HtmlEncode/Decode entfernt keine Zeichen, nicht sicher, wie Sie es empfehlen. –

+0

@AlexeiLevenkov Ja, tut mir leid, ich habe die Frage falsch gelesen ... Ich werde meine Antwort entsprechend aktualisieren. –

1

Wenn Sie wissen, was diese Zeichen sind, können Sie verwenden string.Replace:

newString = oldString.Replace("?", ""); 

wo "?" stellt den Charakter dar, den Sie entfernen möchten.

Der Nachteil dieses Ansatzes besteht darin, dass Sie diesen Aufruf wiederholt durchführen müssen, wenn mehrere Zeichen entfernt werden sollen.

+0

Danke, aber ich kann diesen Ansatz nicht verwenden, weil ich nicht weiß, was der versteckte Char ist. Es erscheint nur in Outlook als ein Fragezeichen. – bradley4

+1

+1. @ Bradley4, wenn Sie nicht wissen, was zu entfernen (oder was zu behalten), wie erwarten Sie, dass Menschen auf Ihre Frage antworten? –

3

Sie dies tun können:

var hChars = new char[] {...}; 
var result = new string(yourString.Where(c => !hChars.Contains(c)).ToArray()); 
+0

Danke, aber ich kann diesen Ansatz nicht verwenden, weil ich nicht weiß, was der versteckte char ist. Es erscheint nur in Outlook als ein Fragezeichen. – bradley4

0

es eine Weile, war aber Dies wurde noch nicht beantwortet.

Wie fügen Sie den HMTL-Inhalt in den Sendecode ein? Wenn Sie es aus einer Datei lesen, überprüfen Sie die Dateicodierung. Wenn Sie UTF-8 mit Signatur verwenden (der Name variiert leicht zwischen den Editoren), kann dies am Anfang der E-Mail zu einem komischen Zeichen führen.

12

Normalerweise verwende ich diesen regulären Ausdruck, um alle nicht druckbaren Zeichen zu ersetzen.

Übrigens denken die meisten Leute, dass Tab, Zeilenvorschub und Wagenrücklauf nicht druckbare Zeichen sind, aber für mich sind sie nicht.

So, hier ist der Ausdruck:

string output = Regex.Replace(input, @"[^\u0009\u000A\u000D\u0020-\u007E]", "*"); 
  • ^ bedeutet, wenn es mit einer der folgenden:
  • \u0009 ist Registerkarte
  • \u000A Zeilenvorschub ist
  • \u000D ist Wagenrücklauf
  • \u0020-\u007E bedeutet alles von Spa ce zu ~ - das ist alles in ASCII.

Siehe ASCII table, wenn Sie Änderungen vornehmen möchten. Denken Sie daran, dass es alle Nicht-ASCII-Zeichen entfernen würde.

Um zu testen, über einen String selbst wie folgt erstellen:

string input = string.Empty; 

    for (int i = 0; i < 255; i++) 
    { 
     input += (char)(i); 
    } 
+2

Ich denke, der erste^invertiert die Menge, während die anderen^s nicht da sein sollen (schließt^aus der Ausgabe aus). – Matt

0

String Ausgabe = new String (!. Input.Where (c => char.IsControl (c)) ToArray()) ; Dies wird sicherlich das Problem lösen. Ich hatte einen nicht druckbaren Ersatz characer (ASCII 26) in einer Zeichenkette, die meine app verursacht wurde zu brechen und diese Codezeile entfernt, um die Zeichen

2

Was das Beste für mich gearbeitet ist:

string result = new string(value.Where(c => char.IsLetterOrDigit(c) || (c >= ' ' && c <= byte.MaxValue)).ToArray()); 

Wo ich m stelle sicher, dass das Zeichen ein beliebiger Buchstabe oder eine Ziffer ist, so dass ich keine nicht englischen Buchstaben ignoriere, oder wenn es kein Buchstabe ist, überprüfe ich, ob es ein ASCII-Zeichen ist, das größer oder gleich Space ist Steuerzeichen, dies stellt sicher, dass ich Interpunktion nicht ignoriere.

Einige schlagen vor, IsControl mit überprüfen, ob das Zeichen nicht druckbaren oder nicht, aber das ignoriert Links-Rechts-Markierung zum Beispiel.

3
new string(input.Where(c => !char.IsControl(c)).ToArray()); 

IsControl vermisst einige Steuerzeichen wie von links nach rechts Markierung (LRM) (char, die üblicherweise in einem String versteckt, während Kopieren und Einfügen tun). Wenn Sie sicher sind, dass die Zeichenfolge nur Ziffern und Zahlen, dann können Sie verwenden IsLetterOrDigit

new string(input.Where(c => char.IsLetterOrDigit(c)).ToArray()) 

Wenn Ihr String Sonderzeichen enthält, dann

new string(input.Where(c => c < 128).ToArray()) 
+0

Leider wird der letzte Vorschlag ('new string (input.Where (c => c <128) .ToArray())') von meinem Unit-Test auch akzentuierte Zeichen entfernen. Zum Beispiel wird "Siñalizacíon" zu "Sializacon". –