Hapus karakter non-ascii dalam string

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

dan saya perlu menghapus semua karakter non-ascii dari string,

berarti str hanya berisi "INFO] (Higashikurume)";

Dev
sumber

Jawaban:

234

ASCII berada dalam rentang 0 hingga 127, jadi:

str.replace(/[^\x00-\x7F]/g, "");
Zaffy
sumber
8
@AlexanderMills Cari tabel ascii - Anda dapat melihat bahwa hanya karakter yang memiliki nilai dari nol hingga 127 yang valid. (0x7F adalah 127 dalam hex). Kode ini cocok dengan semua karakter yang tidak ada dalam kisaran ascii dan menghapusnya.
Zaffy
Terima kasih telah berbagi. Maukah Anda menjelaskan cara kerja \ x7F? Terima kasih lagi.
eyyo
1
@eyyo IIt mewakili karakter ascii karakter terakhir. Saya tidak bisa memberi Anda penjelasan lengkap dalam komentar seperti ini. Ini disebut urutan pelarian heksadesimal, jika Anda mencarinya, Anda pasti akan menemukan banyak informasi tentangnya.
Zaffy
32

Itu juga dapat dilakukan dengan pernyataan penghapusan yang positif, seperti ini:

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

Ini menggunakan unicode. Dalam Javascript, saat mengekspresikan unicode untuk ekspresi reguler, karakter ditentukan dengan urutan escape \u{xxxx}tetapi juga 'u'harus ada panji ; perhatikan regex memiliki bendera 'gu'.

Saya menyebutnya sebagai "pernyataan penghapusan positif" dalam arti bahwa pernyataan "positif" mengungkapkan karakter mana yang harus dihapus, sementara pernyataan "negatif" mengungkapkan huruf mana yang tidak boleh dihapus. Dalam banyak konteks, pernyataan negatif, seperti yang dinyatakan dalam jawaban sebelumnya, mungkin lebih sugestif bagi pembaca. Sirkfleks " ^" mengatakan "tidak" dan rentang \x00-\x7Fmengatakan "ascii", jadi keduanya bersama-sama mengatakan "bukan ascii."

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

Itu adalah solusi yang bagus untuk penutur bahasa Inggris yang hanya peduli dengan bahasa Inggris, dan juga jawaban yang bagus untuk pertanyaan awal. Tetapi dalam konteks yang lebih umum, seseorang tidak selalu dapat menerima bias budaya dengan menganggap "semua non-ascii buruk." Untuk konteks di mana non-ascii digunakan, tetapi terkadang perlu dihilangkan, pernyataan positif dari Unicode lebih cocok.

Sebuah indikasi yang baik bahwa lebar-nol, karakter non-pencetakan disematkan dalam sebuah string adalah ketika properti "panjang" string adalah positif (bukan nol), tetapi terlihat seperti (yaitu dicetak sebagai) string kosong. Misalnya, ini muncul di debugger Chrome, untuk variabel bernama "textContent":

> textContent
""
> textContent.length
7

Ini mendorong saya untuk ingin melihat apa yang ada di dalam string itu.

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

Urutan byte ini tampaknya berada dalam keluarga beberapa karakter Unicode yang disisipkan oleh pengolah kata ke dalam dokumen, dan kemudian menemukan jalannya ke bidang data. Paling umum, simbol ini muncul di akhir dokumen. Ruang lebar-nol"%E2%80%8B" mungkin disisipkan oleh 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

Beberapa referensi tentang itu:

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

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

Perhatikan bahwa meskipun pengkodean karakter yang disematkan adalah UTF-8, pengkodean dalam ekspresi reguler tidak. Meskipun karakter disematkan dalam string sebagai tiga byte (dalam kasus saya) UTF-8, instruksi dalam ekspresi reguler harus menggunakan Unicode dua byte. Faktanya, UTF-8 bisa sampai empat byte; ini kurang kompak daripada Unicode karena menggunakan bit tinggi (atau bit) untuk keluar dari pengkodean ascii standar. Itu dijelaskan di sini:

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

IAM_AL_X
sumber
3
textContent = textContent.replace(/[\u{0080}-\u{FFFF}]/gu,"");tidak berfungsi di IE (setidaknya IE 11). Gagal dengan kesalahan: SCRIPT5021 : Rentang tidak valid dalam kumpulan karakter
Andrey Sorich
14

Anda dapat menggunakan regex berikut untuk mengganti karakter non-ASCII

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

Namun, perhatikan bahwa spasi, titik dua, dan koma adalah ASCII yang valid, jadi hasilnya akan seperti itu

> str
"INFO] :, , ,  (Higashikurume)"
Chris Taylor
sumber
Saya tidak hebat dengan regex tetapi tahu metode .replace () mengambil hal yang ingin Anda ganti dan mengganti parameter ke-2 seperti .replace ('ganti teks ini', 'dengan teks ini'). Jadi bagian mana yang mengatakan melakukan yang sebaliknya dan meninggalkan karakter ascii dan menghapus yang lain. Terima kasih.
NicoM
2
@NicoM Karakter []berarti karakter apa pun tetapi dalam [^]arti sebaliknya - cocok dengan karakter apa pun yang tidak ada dalam tanda kurung.
Zaffy
11

Tak satu pun dari jawaban ini menangani tab, baris baru, carriage return dengan benar, dan beberapa tidak menangani ASCII dan unicode yang diperpanjang. Ini akan MENETAP tab & baris baru, tetapi menghapus karakter kontrol dan apa pun di luar kumpulan ASCII. Klik tombol "Jalankan cuplikan kode ini" untuk menguji. Ada beberapa javascript baru yang akan diluncurkan jadi di masa depan (2020+?) Anda mungkin harus melakukannya \u{FFFFF}tetapi belum

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

Jonathan
sumber
ini adalah ekspresi reguler yang bagus, tetapi juga menghilangkan aksen dan emoji. Saya tidak yakin bagaimana meningkatkan regex ini untuk mencakup kasus-kasus ini.
Julio Vedovatto
Bagi siapa pun yang mencari solusi yang mungkin untuk menghapus Angular window.atob dan DOMSanitizer.bypassSecurity ... karakter tidak valid (baik itu% 80, \ uFFFF atau spasi putih yang tidak dapat dijelaskan) saat mengonversi ke base64, ini adalah solusi yang berfungsi
B.Leon
10

Untuk menggunakan ASCII dengan aksen:

var str = str.replace(/[^\x00-\xFF]/g, "");
Eolia
sumber
Cemerlang! Menangani nilai ascii di atas 127 yang dibuang oleh jawaban lain.
pengguna3413723
Bagaimana dengan teks alt dengan aksen ... seperti altcodeunicode.com/alt-codes-letter-e-with-accents ?
Ditumpuk