Wie können Sie Nicht-ASCII-Zeichen aus einer Zeichenfolge entfernen? (in C#)


180

Wie können Sie Nicht-ASCII-Zeichen aus einer Zeichenfolge entfernen? (In C#)

+3

Per sinelaws Antwort [unten] (http://stackoverflow.com/a/10036919/298754), wenn Sie stattdessen * Nicht-ASCII-Zeichen * ersetzen möchten, finden Sie [diese Antwort] (http: // stackoverflow.com/a/10036907/562906) statt **. 10 dez. 132013-12-10 15:37:13

355
string s = "søme string"; 
s = Regex.Replace(s, @"[^\u0000-\u007F]+", string.Empty); 
+14

Für diejenigen von uns RegEx'd herausgefordert, würde es Ihnen etwas ausmachen, in Englisch Ihr RegEx-Muster zu schreiben. Mit anderen Worten, "das tut das", usw. ... 23 sep. 082008-09-23 22:45:15

+42

@Metro Schlumpf der^ist der Nicht-Operator. Es sagt der Regex, dass sie alles findet, was nicht passt, und nicht alles, was passt. Die \ u #### - \ u #### sagt, welche Zeichen übereinstimmen. \ U0000- \ u007F ist das Äquivalent der ersten 255 Zeichen in utf-8 oder Unicode, die immer die ASCII-Zeichen sind. Sie passen also alle nicht ASCII-Zeichen (wegen der nicht) und ersetzen alles, was übereinstimmt. 11 dez. 092009-12-11 21:11:26

+3

nicht 255, 127 .. sorry bout that :) 11 dez. 092009-12-11 21:12:13

+33

Bereich für druckbare Zeichen ist 0020-007E, für Leute, die regulären Ausdruck suchen, um nicht druckbare Zeichen zu ersetzen 17 feb. 142014-02-17 04:40:17

  0

Wenn Sie eine Tabelle des ASCII-Zeichensatzes sehen möchten: http: //www.asciitable.com/ 26 feb. 152015-02-26 15:06:05

  0

Bereich für ** erweitertes ASCII ** ist \ u0000-0000FF, für Leute, die nach regulären Ausdrücken suchen, um nicht erweiterte ASCII-Zeichen zu ersetzen (dh für Anwendungen mit spanischer Sprache, diakritischen Zeichen usw.) 29 dez. 152015-12-29 21:30:50

+1

@GordonTucker \ u0000- \ u007F ist das Äquivalenz der ** ersten 127 Zeichen ** in utf-8 oder Unicode und nicht die ersten 225. Siehe [Tabelle] (http://www.asci-i-code.com/) 29 dez. 152015-12-29 21:33:56

+4

@full_prog_full Was ist der Grund, warum ich mir etwa eine Minute später geantwortet habe, als ich korrigierte, dass es 127 und nicht 255 war. :) 30 dez. 152015-12-30 21:46:35

  0

LED   Expo Thailand ist bereit für seine neue Ausgabe auf   LED   Technologie zum Entfernen von ASCII-Code in C# 10 jan. 182018-01-10 11:46:58


96

Hier ist eine reine .NET-Lösung, die keine regulären Ausdrücke nicht verwendet:

 string inputString = "Räksmörgås"; 
     string asAscii = Encoding.ASCII.GetString(
      Encoding.Convert(
       Encoding.UTF8, 
       Encoding.GetEncoding(
        Encoding.ASCII.EncodingName, 
        new EncoderReplacementFallback(string.Empty), 
        new DecoderExceptionFallback() 
        ), 
       Encoding.UTF8.GetBytes(inputString) 
      ) 
     ); 

Es kann umständlich aussehen, aber es sollte intuitiv sein. Es verwendet die .NET ASCII-Codierung, um eine Zeichenfolge zu konvertieren. UTF8 wird während der Konvertierung verwendet, da es beliebige der ursprünglichen Zeichen darstellen kann. Es verwendet einen EncoderReplacementFallback, um alle Nicht-ASCII-Zeichen in eine leere Zeichenfolge zu konvertieren. Dies ist ungetestet Code

+3

Perfekt! Ich verwende dies, um eine Zeichenfolge zu bereinigen, bevor Sie sie in einem RTF-Dokument speichern. Sehr geschätzt. Viel einfacher zu verstehen als die Regex-Version. 06 okt. 092009-10-06 16:48:26

+18

Sie finden es wirklich leichter zu verstehen? Für mich sind all die Dinge, die nicht wirklich relevant sind (Fallbacks, Konvertierungen in Bytes usw.), die Aufmerksamkeit von dem, was tatsächlich passiert, abzulenken. 11 okt. 092009-10-11 15:28:54

  0

habe ich dieses Beispiel lieben! 16 mär. 112011-03-16 11:03:38

+18

Es ist eine Art zu sagen, dass Schraubendreher zu verwirrend sind, also werde ich stattdessen einen Hammer verwenden. 03 aug. 112011-08-03 22:05:12

+7

@Brandon, tatsächlich, diese Technik macht den Job nicht besser als andere Techniken. Also würde die Analogie mit einem schlichten Oldschraubendreher statt einer schicken iScrewDriver Deluxe 2000 sein. :) 04 aug. 112011-08-04 07:46:09

  0

@bzim Es ist wie mit einem Hammer auf einer Schraube :) OK nicht. Es ist also so, als würde man mit der Kurbelwelle eines Automotors eine Schraube antreiben. Da gehen wir. 22 aug. 112011-08-22 17:10:45

  0

Wie langsam ist das im Vergleich zu Regex? Regex ist ziemlich schnell. 23 mai. 132013-05-23 21:09:24

  0

@InsidiousForce, hängt wahrscheinlich davon ab, welchen regulären Ausdruck Sie verwenden. Warum nimmst du nicht einen der Ausdrücke aus einer der Antworten auf diese Frage und benchtest ihn? :) 27 mai. 132013-05-27 08:36:34

+9

Ein Vorteil ist, dass ich ASCII mit ISO 8859-1 oder einer anderen Codierung leicht ersetzen kann :) 04 jul. 132013-07-04 03:34:35

  0

Wir haben eine Foxpro DB, die unser System verwendet, die für eine Verspätung beschädigt wird. Da diese Funktion auf fast jedem Feld jeder Zeile ausgeführt wird, war ich neugierig auf den Leistungsunterschied und ob es etwas besseres als normale Regexp gab. Für 1.000 zufällig generierte Unicode-Strings lauten die Laufzeiten "Regexp: Avg: 3 ~ 4ms, Max: 4ms" und "Encoding Conversion: Avg: 4 ~ 5ms, Max: 7ms" (ohne String-Generierung außerhalb des Timers) 16 jul. 132013-07-16 11:46:05

  0

@ syserr0r Interessant. Diese Technik könnte wahrscheinlich optimiert werden, je nachdem, was Zeit braucht. Die 2 Fallback-Instanzen könnten beispielsweise wiederverwendet werden. 05 aug. 132013-08-05 12:20:18

  0

Ich finde dies schneller als die Regex auf kleineren Strings (sie sind fast gleich auf 1000 Zeichenfolge) und langsamer auf größere Strings 02 okt. 142014-10-02 15:17:48

  0

Ich frage mich, ob ich dies irgendwie verwenden könnte, um nicht-ASCII-Zeichen durch Ersatzzeichen zu ersetzen. zum Beispiel: 'á' würde durch' a' ersetzt werden. Ist das möglich? 28 dez. 152015-12-28 12:42:01

  0

@RageCompex Der EncoderReplacementFallback wurde nicht für die Konvertierung entwickelt. Aber was Sie wollen, können Sie mit den .NET APIs für Unicode Normalization und Canonicalization erreichen. 30 dez. 152015-12-30 11:19:33


8

von philcruz's Regular Expression solution inspiriert, ich habe

public static string PureAscii(this string source, char nil = ' ') 
    { 
     var min = '\u0000'; 
     var max = '\u007F'; 
     return source.Select(c => c < min ? nil : c > max ? nil : c).ToText(); 
    } 

    public static string ToText(this IEnumerable<char> source) 
    { 
     var buffer = new StringBuilder(); 
     foreach (var c in source) 
      buffer.Append(c); 
     return buffer.ToString(); 
    } 

eine reine LINQ-Lösung hergestellt.

+1

Für diejenigen, die es nicht verstanden haben, ist dies eine C# 4.0 LINQ-basierte Lösung. :) 28 jan. 102010-01-28 20:49:59

+6

Anstelle der separaten ToText() -Methode, wie ersetzen Sie Zeile 3 von PureAscii() mit: return new string (source.Select (c => c <min? Nil: c> max? Nil: c). ZuArray()); 10 nov. 112011-11-10 05:51:56

  0

Oder vielleicht ToText als: return (neue Zeichenkette (Quelle)). ToArray() - je nachdem, was am besten funktioniert. Es ist immer noch schön, ToText als eine Erweiterungsmethode zu haben - fließend/Pipeline-Stil. :-) 15 jan. 162016-01-15 10:14:21

  0

Dieser Code ersetzt Nicht-ASCII-Zeichen durch ein Leerzeichen. Um sie auszublenden, ändern Sie Select to Where: 'return new string (source.Where (c => c> = min & & c <= max). ToArray());' 17 mai. 172017-05-17 20:53:52

  0

@Foozinator Mit diesem Code können Sie angeben, welches Zeichen um die Nicht-ASCII-Zeichen durch zu ersetzen. Standardmäßig verwendet es ein Leerzeichen, aber wenn es wie .PureASCII (Char.MinValue) aufgerufen wird, wird es alle Nicht-ASCII-Zeichen durch '\ 0' ersetzen - was immer noch nicht genau das Entfernen ist, aber ähnliche Ergebnisse. 29 nov. 172017-11-29 16:42:41


13

Wenn Sie nicht wollen, strippen, sondern tatsächlich lateinische akzentuierte zu nicht-akzentuierte Zeichen konvertieren, einen Blick auf diese Frage nehmen: How do I translate 8bit characters into 7bit characters? (i.e. Ü to U)

  0

Ich wusste nicht einmal, dass das möglich ist, aber es ist eine viel bessere Lösung für mich. Ich werde diesen Link zu einem Kommentar zu der Frage hinzufügen, damit andere Personen leichter finden können. Vielen Dank! 10 dez. 132013-12-10 15:36:16


1

ich diesen regulären Ausdruck verwendet:

string s = "søme string"; 
    Regex regex = new Regex(@"[^a-zA-Z0-9\s]", (RegexOptions)0); 
    return regex.Replace(s, ""); 
+15

Das entfernt auch Interpunktion, nur für den Fall, dass das nicht was jemand will. 18 jul. 122012-07-18 08:43:26


4

gefunden der folgende leicht geänderte Bereich, der nützlich ist, um Kommentarblöcke aus einer Datenbank zu analysieren, bedeutet, dass Sie nicht mit Tab- und Escape-Zeichen zurechtkommen müssen, was dazu führen würde, dass ein CSV-Feld gestört wird.

parsememo = Regex.Replace(parsememo, @"[^\u001F-\u007F]", string.Empty); 

Wenn Sie andere Sonderzeichen oder besondere Zeichensetzung überprüfen the ascii table

+1

Falls jemand die anderen Kommentare nicht bemerkt hat, sind die druckbaren Zeichen tatsächlich @ "[^ \ u0020- \ u007E]". Hier ist ein Link, um die Tabelle zu sehen, wenn Sie neugierig sind: http://www.asciitable.com/ 26 feb. 152015-02-26 15:03:47


6

keine Notwendigkeit für regex vermeiden wollen. nur Codierung verwenden ...

sOutput = System.Text.Encoding.ASCII.GetString(System.Text.Encoding.ASCII.GetBytes(sInput)); 
  0

+1 große Antwort und die einfachste aus den oben aufgeführten ... 25 aug. 132013-08-25 09:50:07

+5

Dies funktioniert nicht. Dies entfernt Unicode-Zeichen nicht, ersetzt sie durch die? Charakter. 27 feb. 142014-02-27 16:56:11

+1

@David hat Recht. Zumindest habe ich '???? nacho ??', als ich es versuchte: 'た ま ね こ nacho な ち' in Mono 3.4 06 aug. 142014-08-06 02:38:08

  0

Sie können Ihre eigene Codierungsklasse instanziieren, die statt Zeichen zu ersetzen sie entfernt. Siehe die GetEncoding-Methode: https://msdn.microsoft.com/en-us/library/89856k4b(v=vs.110).aspx 01 apr. 162016-04-01 13:52:47


25

Ich glaube MonsCamus gemeint:

parsememo = Regex.Replace(parsememo, @"[^\u0020-\u007E]", string.Empty); 
+1

IMHO Diese Antwort ist besser als die angenommene Antwort, weil es Steuerzeichen ausstreicht. 25 sep. 172017-09-25 14:30:53

  0

LED &#160; Expo Thailand ist bereit für seine neue Ausgabe auf &#160; LED &#160; Technologie, wie ASCII-Code in C# 10 jan. 182018-01-10 11:46:39


2

Diese nicht optimale Performance-weise, aber ein ziemlich geradlinig Linq Ansatz:

string strippedString = new string(
    yourString.Where(c => c <= sbyte.MaxValue).ToArray() 
    ); 

Die Nachteil ist, dass alle "überlebenden" Zeichen zuerst in ein Array vom Typ char[] gelegt werden, das dann weggeworfen wird, nachdem der string Konstruktor es nicht mehr benutzt.


2

Ich kam hier auf der Suche nach einer Lösung für erweiterte ASCII-Zeichen, aber konnte es nicht finden. Der nächste, den ich gefunden habe, ist bzlm's solution. Aber das funktioniert nur für ASCII-Code bis 127 (natürlich können Sie den Kodierungstyp in seinem Code ersetzen, aber ich denke, es war ein bisschen kompliziert zu verstehen. Daher diese Version zu teilen). Hier ist eine Lösung, die für extended ASCII codes i.e. upto 255 arbeitet, die die ISO 8859-1

Es findet und Streifen aus Nicht-ASCII-Zeichen (größer als 255)

Dim str1 as String= "â, ??î or ôu� n☁i✑++$-♓!‼⁉4⃣od;/⏬'®;☕:☝)///[email protected]#" 

Dim extendedAscii As Encoding = Encoding.GetEncoding("ISO-8859-1", 
               New EncoderReplacementFallback(String.empty), 
               New DecoderReplacementFallback()) 

Dim extendedAsciiBytes() As Byte = extendedAscii.GetBytes(str1) 

Dim str2 As String = extendedAscii.GetString(extendedAsciiBytes) 

console.WriteLine(str2) 
'Output : â, ??î or ôu ni++$-!‼⁉4od;/';:)///[email protected]#$%^yz: 

Hier ist ein working fiddle for the code

Ersetzen Sie die Codierung nach der Anforderung , Ruhe sollte gleich bleiben.


0

Ich benutze diesen regulären Ausdruck, um schlechte Zeichen in einem Dateinamen herauszufiltern.

Regex.Replace(directory, "[^a-zA-Z0-9\\:_\- ]", "") 

Das sollten alle Zeichen sein, die für Dateinamen erlaubt sind.

  0

Nö zu entfernen. Siehe [Path.GetInvalidPathChars] (https://msdn.microsoft.com/en-us/library/system.io.path.getinvalidpathchars (v = vs.110) .aspx) und [Path.GetInvalidFileNameChars] (https://msdn.microsoft.com/en-us/library/system.io.path.getinvalidfilenamechars(v=vs.110).aspx). Also, es gibt Zehntausende von gültigen Zeichen. 10 jun. 172017-06-10 00:04:42

  0

Sie haben Recht, Tom. Ich habe tatsächlich an die üblichen gedacht, aber ich habe Klammern und geschweifte Klammern sowie all diese weggelassen - ^% $ # @! & + =. 12 jun. 172017-06-12 20:02:35