Как игнорировать странные utf8 символы но оставлять буквы (иероглифы)?

Я хотел бы сделать код, сохраняющий арабские/китайские/японские никнеймы, но не дающий сохранить что-то вот такое: ̸̧̤̺͕̮̮͇̱̺̥̭̃̋̐͐̀̏͊̍̒̏͌̉̓̔̕ͅ


Ответы (1 шт):

Автор решения: vsemozhebuty

Насколько я понимаю, в вашем примере под запрет попадает группа символов, относящаяся к категории Юникода «Nonspacing Mark». Вы можете исключить её, используя Unicode property escapes:

let str = 'что-то вот такое: ̸̧̤̺͕̮̮͇̱̺̥̭̃̋̐͐̀̏͊̍̒̏͌̉̓̔̕ͅ';

console.log(str);
console.log(inspectString(str));

str = str.replace(/\p{Nonspacing_Mark}+/gu, '');

console.log(str);
console.log(inspectString(str));

function inspectString(string) {
  return [...str].map(
    ch => [ch, `U+${ch.codePointAt(0).toString(16).padStart(4, '0')}`]);
}

Подробнее:

https://2ality.com/2017/07/regexp-unicode-property-escapes.html https://mathiasbynens.be/notes/es-unicode-property-escapes

Но если вы не очень хорошо знаете языки, с которыми предстоит работать, такая огульная чистка может удалить и какие-то полезные символы.

UPD

Предлагаю алгоритм разрешения подобных проблем.

  1. Находите code point символов при помощи вспомогательной функции из примера ниже.
  2. Гуглите это число в шаблоне U+число, переходите на сайт вроде этого: https://www.fileformat.info/info/unicode/char/12031/index.htm
  3. Ищите в описании подходящие свойства символа — общую категорию Юникода, скрипт, бинарное свойство и т.д.
  4. Подбираете подходящее регулярное выражение. Возможно, пригодится эта заметка: https://habr.com/ru/post/350448/ (в каких-то детялях может быть уже немного устаревшей).

let str = 'такие ? можно';

console.log(str);
console.log(inspectString(str));

str = str.replace(/\p{Script_Extensions=Cuneiform}+/gu, '');

console.log(str);
console.log(inspectString(str));

function inspectString(string) {
  return [...str].map(
    ch => [ch, `U+${ch.codePointAt(0).toString(16).padStart(4, '0')}`]);
}

→ Ссылка