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:
ASCII nằm trong khoảng từ 0 đến 127, do đó:
str.replace(/[^\x00-\x7F]/g, "");
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-\x7F
cho 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:
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ự
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)"
[]
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.
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, ''))
Để sử dụng ASCII có dấu:
var str = str.replace(/[^\x00-\xFF]/g, "");