Xóa ký tự không phải ascii trong chuỗi


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

và tôi cần xóa tất cả ký tự không phải ascii khỏi chuỗi,

có nghĩa là str chỉ chứa "INFO] (Higashikurume)";

Câu trả lời:


229

ASCII nằm trong khoảng từ 0 đến 127, do đó:

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

8
@AlexanderMills Tìm kiếm bảng ascii - bạn có thể thấy rằng chỉ các ký tự có giá trị từ 0 đến 127 mới hợp lệ. (0x7F là 127 trong hệ thập lục phân). Mã này khớp với tất cả các ký tự không nằm trong phạm vi ascii và loại bỏ chúng.
Zaffy

31

Nó cũng có thể được thực hiện với một khẳng định tích cực về việc loại bỏ, như sau:

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

Điều này sử dụng unicode. Trong Javascript, khi biểu thị unicode cho một biểu thức chính quy, các ký tự được chỉ định với trình tự thoát \u{xxxx}nhưng cũng 'u'phải xuất hiện cờ ; lưu ý regex có cờ 'gu'.

Tôi gọi đây là "khẳng định tích cực về việc loại bỏ" theo nghĩa là khẳng định "tích cực" thể hiện các ký tự cần loại bỏ, trong khi khẳng định "tiêu cực" thể hiện các chữ cái nào không được xóa. Trong nhiều ngữ cảnh, khẳng định phủ định, như đã nêu trong các câu trả lời trước, có thể gợi ý hơn cho người đọc. Dấu mũ " ^" cho biết "không phải" và phạm vi \x00-\x7Fcho biết "ascii", vì vậy cả hai cùng nói "không phải ascii".

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

Đó là một giải pháp tuyệt vời cho những người nói tiếng Anh chỉ quan tâm đến ngôn ngữ tiếng Anh và nó cũng là một câu trả lời tốt cho câu hỏi ban đầu. Nhưng trong một bối cảnh tổng quát hơn, không phải lúc nào người ta cũng có thể chấp nhận thành kiến ​​văn hóa khi cho rằng "tất cả những người không phải ascii đều xấu." Đối với các ngữ cảnh mà không phải ascii được sử dụng, nhưng đôi khi cần được loại bỏ, khẳng định tích cực của Unicode là phù hợp hơn.

Một dấu hiệu tốt cho thấy các ký tự có độ rộng bằng 0, không in được nhúng vào một chuỗi là khi thuộc tính "độ dài" của chuỗi là số dương (khác không), nhưng trông giống như (tức là in dưới dạng) một chuỗi rỗng. Ví dụ: tôi đã có điều này hiển thị trong trình gỡ lỗi Chrome, cho một biến có tên "textContent":

> textContent
""
> textContent.length
7

Điều này khiến tôi muốn xem những gì có trong chuỗi đó.

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

Chuỗi byte này dường như nằm trong họ một số ký tự Unicode được bộ xử lý văn bản chèn vào tài liệu, sau đó tìm đường vào các trường dữ liệu. Thông thường nhất, những ký hiệu này xuất hiện ở cuối tài liệu. Không gian-width-space "%E2%80%8B"có thể được chèn bởi 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

Một số tài liệu tham khảo về:

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

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

Lưu ý rằng mặc dù mã hóa của ký tự được nhúng là UTF-8, nhưng mã hóa trong biểu thức chính quy thì không. Mặc dù ký tự được nhúng trong chuỗi dưới dạng ba byte (trong trường hợp của tôi) của UTF-8, các lệnh trong biểu thức chính quy phải sử dụng Unicode hai byte. Trên thực tế, UTF-8 có thể dài tới bốn byte; nó kém gọn gàng hơn Unicode vì nó sử dụng bit cao (hoặc các bit) để thoát khỏi bảng mã ascii tiêu chuẩn. Điều đó được giải thích ở đây:

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


3
textContent = textContent.replace(/[\u{0080}-\u{FFFF}]/gu,"");không hoạt động trong IE (ít nhất là IE 11). Nó không thành công với lỗi: SCRIPT5021 : Phạm vi không hợp lệ trong bộ ký tự
Andrey Sorich

14

Bạn có thể sử dụng regex sau để thay thế các ký tự không phải ASCII

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

Tuy nhiên, lưu ý rằng dấu cách, dấu hai chấm và dấu phẩy đều là ASCII hợp lệ, vì vậy kết quả sẽ là

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

Tôi không giỏi với regex nhưng biết phương thức .replace () lấy thứ mà bạn muốn thay thế và thay thế tham số thứ 2 như .replace ('thay thế văn bản này', 'bằng văn bản này'). Vì vậy, phần nào của điều đó nói làm ngược lại và để lại các ký tự ascii và loại bỏ các ký tự khác. Cảm ơn.
NicoM

2
@NicoM Các ký tự []có nghĩa là bất kỳ ký tự nào nhưng [^]có nghĩa là ngược lại - khớp với bất kỳ ký tự nào không có trong ngoặc.
Zaffy

10

Không câu trả lời nào trong số này xử lý đúng các tab, dòng mới, dấu xuống dòng và một số câu trả lời không xử lý ASCII và unicode mở rộng. Thao tác này sẽ GIỮ các tab & dòng mới, nhưng xóa các ký tự điều khiển và bất kỳ thứ gì ngoài bộ ASCII. Nhấp vào nút "Chạy đoạn mã này" để kiểm tra. Có một số javascript mới sắp ra mắt nên trong tương lai (2020+?) Bạn có thể phải làm \u{FFFFF}nhưng chưa

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


nó là một regex tốt, nhưng nó cũng xóa dấu và biểu tượng cảm xúc. Tôi không chắc cách cải thiện regex này để giải quyết những trường hợp này.
Julio Vedovatto

Đối với bất kỳ ai đang tìm kiếm giải pháp khả thi để xóa Angular window.atob và DOMSanitizer.bypassSecurity ... các ký tự không hợp lệ (có thể là% 80, \ uFFFF hoặc khoảng trắng không giải thích được) khi chuyển đổi sang base64, đây là một giải pháp hiệu quả
B. León

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.