Видалити символ, який не є ascii, у рядку


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

і мені потрібно видалити всі символи, що не є ascii, із рядка,

означає str містить лише "INFO] (Хігасікуруме)";

Відповіді:


229

ASCII знаходиться в діапазоні від 0 до 127, отже:

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

8
@AlexanderMills Шукайте таблицю ascii - ви бачите, що дійсними є лише символи, що мають значення від нуля до 127. (0x7F дорівнює 127 у шістнадцятковій). Цей код відповідає всім символам, що не входять до діапазону ascii, і видаляє їх.
Zaffy

31

Це також можна зробити з позитивним твердженням про видалення, наприклад:

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

Тут використовується Unicode. У Javascript, під час вираження Unicode для регулярного виразу, символи вказуються з послідовністю екранування, \u{xxxx}але також 'u'повинен міститись прапор ; зверніть увагу, що регулярний вираз має прапори 'gu'.

Я назвав це "позитивним твердженням про видалення" в тому сенсі, що "позитивне" твердження виражає, яких символів видалити, тоді як "негативне" твердження виражає, які літери не слід видаляти. У багатьох контекстах негативне твердження, як зазначено в попередніх відповідях, може бути більш сугестивним для читача. Циркумфлекс " ^" говорить "ні", а діапазон \x00-\x7F- "ascii", тому обидва разом говорять "не ascii".

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

Це чудове рішення для тих, хто говорить англійською мовою, які піклуються лише про англійську мову, а також чудова відповідь на вихідне запитання. Але в більш загальному контексті не завжди можна прийняти культурну упередженість припущення, що "все, що не є асоціацією, є поганим". Для контекстів, де використовується non-ascii, але час від часу його потрібно виключати, позитивне твердження Unicode краще підходить.

Хорошим показником того, що символи нульової ширини, що не друкуються, є вбудовані в рядок, коли властивість рядка "length" є позитивною (ненульовою), але виглядає як (тобто друкується як) порожній рядок. Наприклад, у мене таке з’явилось у налагоджувачі Chrome для змінної з назвою "textContent":

> textContent
""
> textContent.length
7

Це спонукало мене захотіти побачити, що знаходиться в цій рядку.

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

Здається, ця послідовність байтів є у сімействі деяких символів Unicode, які вставляються текстовими процесорами в документи, а потім знаходять шлях до полів даних. Найчастіше ці символи зустрічаються в кінці документа. Простір нульової ширини "%E2%80%8B"може бути вставлений CK-редактором (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

Деякі посилання на них:

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

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

Зауважте, що хоча кодування вбудованого символу є UTF-8, кодування в регулярному виразі не є. Хоча символ вбудований у рядок як три байти (у моєму випадку) UTF-8, інструкції в регулярному виразі повинні використовувати двобайтовий Unicode. Насправді UTF-8 може мати до чотирьох байт; він менш компактний, ніж Unicode, оскільки використовує старший біт (або біти), щоб уникнути стандартного кодування ascii. Це пояснюється тут:

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


3
textContent = textContent.replace(/[\u{0080}-\u{FFFF}]/gu,"");не працює в IE (принаймні IE 11). Помилка не вдається: SCRIPT5021 : Недійсний діапазон у наборі символів
Андрій Соріч

14

Ви можете використовувати наступний регулярний вираз для заміни символів, що не належать до ASCII

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

Однак зауважте, що пробіли, двокрапки та коми є дійсними ASCII, тож результат буде

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

Я не чудовий з регулярним виразом, але знаю, що метод .replace () бере те, що ви хочете замінити, і замінює другий параметр, наприклад .replace ('замінити цей текст', 'на цей текст'). Тож яка частина сказаного робить навпаки і залишає символи ascii, а інших прибирає. Дякую.
NicoM

2
@NicoM Символи []означають будь-який символ, але [^]означають протилежне - збігаються з будь-якими символами, не в дужках.
Zaffy

11

Жодна з цих відповідей не обробляє належним чином вкладки, нові рядки, повернення каретки, а деякі не обробляють розширений ASCII та Unicode. Це Зберігатиме вкладки та нові рядки, але вилучатиме контрольні символи та все, що не входить до набору ASCII. Натисніть кнопку "Запустити цей фрагмент коду", щоб перевірити. Є якийсь новий javascript, що з’являється, тому в майбутньому (2020+?), Можливо, вам доведеться це зробити, \u{FFFFF}але поки що ні

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


це хороший регулярний вираз, але він також видаляє акценти та смайли. Я не впевнений, як покращити цей регулярний вираз для охоплення цих випадків.
Хуліо Ведовато,

Для тих, хто шукає можливе рішення для видалення Angular window.atob та DOMSanitizer.bypassSecurity ... недійсних символів (будь то% 80, \ uFFFF або незрозумілі пробіли) при перетворенні на base64, це робоче рішення
Б. Леон,

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.