Rimuovi il carattere non ASCII nella stringa


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

e devo rimuovere tutti i caratteri non ASCII dalla stringa,

significa che str contiene solo "INFO] (Higashikurume)";

Risposte:


234

ASCII è compreso tra 0 e 127, quindi:

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

8
@AlexanderMills Cerca una tabella ASCII: puoi vedere che sono validi solo i caratteri con un valore compreso tra zero e 127. (0x7F è 127 in esadecimale). Questo codice corrisponde a tutti i caratteri che non sono nell'intervallo ASCII e li rimuove.
Zaffy

grazie per la condivisione. Ti dispiacerebbe spiegare come funziona \ x7F? Grazie ancora.
eyyo

1
@eyyo IIt rappresenta l'ultimo carattere ASCII. Non posso darti una spiegazione completa in un commento come questo. Si chiama sequenza di escape esadecimale, se la cerchi, troverai sicuramente tonnellate di informazioni a riguardo.
Zaffy

32

Può anche essere fatto con un'affermazione positiva di rimozione, come questa:

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

Questo utilizza Unicode. In Javascript, quando si esprime unicode per un'espressione regolare, i caratteri sono specificati con la sequenza di escape \u{xxxx}ma 'u'deve essere presente anche il flag ; nota che la regex ha delle bandiere 'gu'.

L'ho chiamata "affermazione positiva di rimozione" nel senso che un'asserzione "positiva" esprime quali caratteri rimuovere, mentre un'affermazione "negativa" esprime quali lettere non rimuovere. In molti contesti, l'affermazione negativa, come affermato nelle risposte precedenti, potrebbe essere più suggestiva per il lettore. Il circonflesso " ^" dice "non" e l'intervallo \x00-\x7Fdice "ascii", quindi i due insieme dicono "non ascii".

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

Questa è un'ottima soluzione per chi parla inglese a cui interessa solo la lingua inglese, ed è anche un'ottima risposta per la domanda originale. Ma in un contesto più generale, non si può sempre accettare il pregiudizio culturale di presumere che "tutti i non ASCII siano cattivi". Per i contesti in cui viene utilizzato non ASCII, ma a volte deve essere eliminato, l'affermazione positiva di Unicode è più adatta.

Una buona indicazione che i caratteri di larghezza zero e non stampabili sono incorporati in una stringa è quando la proprietà "length" della stringa è positiva (diversa da zero), ma sembra (cioè viene stampata come) una stringa vuota. Ad esempio, avevo questo visualizzato nel debugger di Chrome, per una variabile denominata "textContent":

> textContent
""
> textContent.length
7

Questo mi ha spinto a voler vedere cosa c'era in quella stringa.

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

Questa sequenza di byte sembra essere nella famiglia di alcuni caratteri Unicode che vengono inseriti dagli elaboratori di testi nei documenti e poi trovano la loro strada nei campi dati. Più comunemente, questi simboli si trovano alla fine di un documento. Lo spazio di larghezza zero "%E2%80%8B"potrebbe essere inserito da CK-Editor (CKEditor).

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

Alcuni riferimenti su quelli:

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

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

Notare che sebbene la codifica del carattere incorporato sia UTF-8, la codifica nell'espressione regolare non lo è. Sebbene il carattere sia incorporato nella stringa come tre byte (nel mio caso) di UTF-8, le istruzioni nell'espressione regolare devono utilizzare Unicode a due byte. In effetti, UTF-8 può essere lungo fino a quattro byte; è meno compatto di Unicode perché usa il bit (o i bit) alto per sfuggire alla codifica ascii standard. Questo è spiegato qui:

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


3
textContent = textContent.replace(/[\u{0080}-\u{FFFF}]/gu,"");non funziona in IE (almeno IE 11). Non riesce con errore: SCRIPT5021 : intervallo non valido nel set di caratteri
Andrey Sorich

14

È possibile utilizzare la seguente regex per sostituire i caratteri non ASCII

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

Tuttavia, tieni presente che gli spazi, i due punti e le virgole sono tutti ASCII validi, quindi il risultato sarà

> str
"INFO] :, , ,  (Higashikurume)"

Non sono bravo con regex ma so che il metodo .replace () prende la cosa che vuoi sostituire e sostituisce il secondo parametro come .replace ('sostituisci questo testo', 'con questo testo'). Quindi quale parte di questo dice fai il contrario e lascia i caratteri ASCII e rimuovi gli altri. Grazie.
NicoM

2
@NicoM Caratteri []significa qualsiasi carattere, ma [^]significa l'opposto: trova qualsiasi carattere non tra parentesi.
Zaffy

11

Nessuna di queste risposte gestisce correttamente tabulazioni, ritorni a capo, ritorni a capo e alcune non gestiscono ASCII estesi e unicode. Questo MANTERRÀ le tabulazioni e le nuove righe, ma rimuoverà i caratteri di controllo e qualsiasi cosa al di fuori del set ASCII. Fai clic sul pulsante "Esegui questo frammento di codice" per eseguire il test. C'è del nuovo javascript in arrivo, quindi in futuro (2020+?) Potresti doverlo fare \u{FFFFF}ma non ancora

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


è una buona regex, ma rimuove anche gli accenti e gli emoji. Non sono sicuro di come migliorare questa regex per coprire questi casi.
Julio Vedovatto

Per chiunque cerchi una possibile soluzione per rimuovere Angular window.atob e DOMSanitizer.bypassSecurity ... caratteri non validi (siano% 80, \ uFFFF o spazi bianchi inspiegabili) durante la conversione in base64, questa è una soluzione funzionante
B. León

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.