Entfernen Sie Nicht-ASCII-Zeichen in der Zeichenfolge

85
var str="INFO] :谷���新道, ひば���ヶ丘2丁���, ひばりヶ���, 東久留米市 (Higashikurume)";

und ich muss alle Nicht-ASCII-Zeichen aus der Zeichenfolge entfernen,

bedeutet, dass str nur "INFO] (Higashikurume)" enthält;

Dev
quelle

Antworten:

225

ASCII liegt im Bereich von 0 bis 127, also:

str.replace(/[^\x00-\x7F]/g, "");
Zaffy
quelle
8
@AlexanderMills Suche nach einer ASCII-Tabelle - Sie können sehen, dass nur Zeichen mit einem Wert von Null bis 127 gültig sind. (0x7F ist 127 in hex). Dieser Code stimmt mit allen Zeichen überein, die nicht im ASCII-Bereich liegen, und entfernt sie.
Zaffy
30

Dies kann auch mit einer positiven Behauptung der Entfernung erfolgen, wie folgt:

textContent = textContent.replace(/[\u{0080}-\u{FFFF}]/gu,"");

Dies verwendet Unicode. In Javascript werden beim Ausdrücken von Unicode für einen regulären Ausdruck die Zeichen mit der Escape-Sequenz angegeben, \u{xxxx}aber auch das Flag 'u'muss vorhanden sein. Beachten Sie, dass der Regex Flags hat 'gu'.

Ich nannte dies eine "positive Behauptung der Entfernung" in dem Sinne, dass eine "positive" Behauptung ausdrückt, welche Zeichen entfernt werden sollen, während eine "negative" Behauptung ausdrückt, welche Buchstaben nicht entfernt werden sollen. In vielen Zusammenhängen könnte die negative Behauptung, wie in den vorherigen Antworten angegeben, für den Leser suggestiver sein. Der Zirkumflex " ^" sagt "nicht" und der Bereich \x00-\x7Fsagt "ascii", also sagen die beiden zusammen "nicht ascii".

textContent = textContent.replace(/[^\x00-\x7F]/g,"");

Dies ist eine großartige Lösung für englischsprachige Personen, die sich nur für die englische Sprache interessieren, und eine gute Antwort auf die ursprüngliche Frage. In einem allgemeineren Kontext kann man jedoch nicht immer die kulturelle Tendenz akzeptieren, anzunehmen, dass "alle Nicht-ASCII schlecht sind". Für Kontexte, in denen Nicht-ASCII verwendet wird, aber gelegentlich entfernt werden müssen, ist die positive Behauptung von Unicode besser geeignet.

Ein guter Hinweis darauf, dass nicht druckbare Zeichen mit einer Breite von Null in eine Zeichenfolge eingebettet sind, ist, wenn die Eigenschaft "Länge" der Zeichenfolge positiv ist (ungleich Null), aber wie eine leere Zeichenfolge aussieht (dh als solche gedruckt wird). Zum Beispiel wurde dies im Chrome-Debugger für eine Variable mit dem Namen "textContent" angezeigt:

> textContent
""
> textContent.length
7

Dies veranlasste mich zu sehen, was in dieser Zeichenfolge war.

> encodeURI(textContent)
"%E2%80%8B%E2%80%8B%E2%80%8B%E2%80%8B%E2%80%8B%E2%80%8B%E2%80%8B"

Diese Folge von Bytes scheint zur Familie einiger Unicode-Zeichen zu gehören, die von Textverarbeitungsprogrammen in Dokumente eingefügt werden und dann in Datenfelder gelangen. Am häufigsten treten diese Symbole am Ende eines Dokuments auf. Der Raum mit der Breite Null "%E2%80%8B"kann vom CK-Editor (CKEditor) eingefügt werden.

encodeURI()  UTF-8     Unicode  html     Meaning
-----------  --------  -------  -------  -------------------
"%E2%80%8B"  EC 80 8B  U 200B   ​  zero-width-space
"%E2%80%8E"  EC 80 8E  U 200E   ‎  left-to-right-mark
"%E2%80%8F"  EC 80 8F  U 200F   ‏  right-to-left-mark

Einige Referenzen zu diesen:

http://www.fileformat.info/info/unicode/char/200B/index.htm

https://en.wikipedia.org/wiki/Left-to-right_mark

Beachten Sie, dass die Codierung des eingebetteten Zeichens zwar UTF-8 ist, die Codierung im regulären Ausdruck jedoch nicht. Obwohl das Zeichen als drei Bytes (in meinem Fall) von UTF-8 in die Zeichenfolge eingebettet ist, müssen die Anweisungen im regulären Ausdruck den Zwei-Byte-Unicode verwenden. Tatsächlich kann UTF-8 bis zu vier Bytes lang sein. Es ist weniger kompakt als Unicode, da es das High-Bit (oder die High-Bits) verwendet, um der Standard-ASCII-Codierung zu entkommen. Das wird hier erklärt:

https://en.wikipedia.org/wiki/UTF-8

IAM_AL_X
quelle
3
textContent = textContent.replace(/[\u{0080}-\u{FFFF}]/gu,"");funktioniert nicht im IE (mindestens IE 11). Es schlägt mit Fehler fehl: SCRIPT5021 : Ungültiger Bereich im Zeichensatz
Andrey Sorich
14

Sie können den folgenden regulären Ausdruck verwenden, um Nicht-ASCII-Zeichen zu ersetzen

str = str.replace(/[^A-Za-z 0-9 \.,\?""!@#\$%\^&\*\(\)-_=\+;:<>\/\\\|\}\{\[\]`~]*/g, '')

Beachten Sie jedoch, dass Leerzeichen, Doppelpunkte und Kommas alle gültige ASCII-Werte sind, sodass das Ergebnis angezeigt wird

> str
"INFO] :, , ,  (Higashikurume)"
Chris Taylor
quelle
Ich bin nicht besonders gut mit Regex, aber ich weiß, dass die .replace () -Methode das Ding verwendet, das Sie ersetzen möchten, und den zweiten Parameter wie .replace ersetzt ('diesen Text ersetzen', 'durch diesen Text'). Also, welcher Teil davon sagt, machen Sie das Gegenteil und lassen Sie die ASCII-Zeichen und entfernen Sie die anderen. Vielen Dank.
NicoM
2
@NicoM Zeichen []bedeuten jedes Zeichen, aber im [^]Gegenteil - stimmen mit jedem Zeichen überein, das nicht in Klammern steht.
Zaffy
9

Keine dieser Antworten behandelt Tabulatoren, Zeilenumbrüche und Zeilenumbrüche ordnungsgemäß, und einige behandeln nicht erweitertes ASCII und Unicode. Dadurch werden Tabulatoren und Zeilenumbrüche beibehalten, aber Steuerzeichen und alles aus dem ASCII-Satz entfernt. Klicken Sie zum Testen auf die Schaltfläche "Code-Snippet ausführen". Es kommt ein neues Javascript auf den Markt, sodass Sie es in Zukunft (2020+?) Möglicherweise tun müssen, \u{FFFFF}aber noch nicht

console.log("line 1\nline2 \n\ttabbed\nF̸̡̢͓̳̜̪̟̳̠̻̖͐̂̍̅̔̂͋͂͐l̸̢̹̣̤̙͚̱͓̖̹̻̣͇͗͂̃̈͝a̸̢̡̬͕͕̰̖͍̮̪̬̍̏̎̕͘ͅv̸̢̛̠̟̄̿i̵̮͌̑ǫ̶̖͓͎̝͈̰̹̫͚͓̠̜̓̈́̇̆̑͜ͅ".replace(/[\x00-\x08\x0E-\x1F\x7F-\uFFFF]/g, ''))

Jonathan
quelle
Es ist eine gute Regex, entfernt aber auch Akzente und Emojis. Ich bin mir nicht sicher, wie ich diesen regulären Ausdruck verbessern kann, um diese Fälle abzudecken.
Julio Vedovatto
Für alle, die nach einer möglichen Lösung zum Entfernen von Angular window.atob und DOMSanitizer.bypassSecurity suchen ... ungültige Zeichen (sei es% 80, \ uFFFF oder ungeklärte Leerzeichen) bei der Konvertierung in base64 ist dies eine funktionierende Lösung
B. León
8

So verwenden Sie ASCII mit Akzenten:

var str = str.replace(/[^\x00-\xFF]/g, "");
Eolia
quelle
Brillant! Behandelt ASCII-Werte über 127, die andere Antworten wegwerfen.
user3413723