Удалить не-ascii-символ в строке


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

и мне нужно удалить все символы, отличные от ascii, из строки,

означает, что строка содержит только "INFO] (Higashikurume)";

Ответы:


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,"");

Здесь используется юникод. В Javascript при выражении юникода для регулярного выражения символы указываются с помощью escape-последовательности, \u{xxxx}но также 'u'должен присутствовать флаг ; обратите внимание, что у регулярного выражения есть флаги 'gu'.

Я назвал это «положительным утверждением об удалении» в том смысле, что «положительное» утверждение выражает, какие символы следует удалить, а «отрицательное» утверждение выражает, какие буквы не удалять. Во многих контекстах отрицательное утверждение, как было сказано в предыдущих ответах, может быть более наводящим на читателя. Циркумфлекс " ^" говорит "не", а диапазон \x00-\x7F- "ascii", поэтому оба вместе говорят "not ascii".

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

Это отличное решение для англоговорящих людей, которым важен только английский язык, а также прекрасный ответ на исходный вопрос. Но в более общем контексте нельзя всегда принять культурную предвзятость предположения, что «все не-ascii - это плохо». Для контекстов, в которых используется не 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-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

Некоторые ссылки на те:

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 08

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.