Как отфильтровать строку, чтобы оставить только буквы с помощью регулярных выражений в JavaScript
Что проверяют
Умеете ли вы писать регулярные выражения с учётом Unicode, а не только для латиницы. Следом почти всегда спрашивают: а если в строке будут немецкие умляуты, греческий или эмодзи?
Как отвечать
Сначала уточните условие: остаются ли пробелы, какие алфавиты ожидаются. Потом дайте решение:
const onlyLetters = (s) => s.replace(/[^\p{L}]/gu, '');
onlyLetters('Привет, мир! 123 Ärger'); // 'ПриветмирÄrger'Разберите его по частям:
\p{L}: Unicode property escape, любая буква любого алфавита. Работает только с флагомuилиv, поддерживается с ES2018 во всех актуальных браузерах;[^...]: отрицание класса, всё, что не буква, заменяется пустой строкой;g: без негоreplaceуберёт только первое совпадение. СreplaceAllфлагgобязателен, иначе будетTypeError;- комбинируемые знаки: «й» может прийти в разложенном виде, как «и» плюс отдельный знак U+0306. Этот знак относится к категории
\p{M}, и фильтр по\p{L}превратит «й» в «и». Лечитсяs.normalize('NFC')перед заменой или классом[^\p{L}\p{M}].
Вариант /[^a-zA-Zа-яА-ЯёЁ]/g тоже рабочий, если нужны строго латиница и кириллица. Про него стоит знать одну деталь: ё и Ё лежат вне диапазонов а-я и А-Я, поэтому их перечисляют отдельно. Можно искать, а не заменять: s.match(/\p{L}+/gu)?.join('') ?? '', потому что match без совпадений возвращает null.
В интерфейсе молча вырезать символы из поля ввода часто хуже, чем подсветить ошибку: пользователь не понимает, куда делся текст, а каретка прыгает в конец.
Где спотыкаются
Используют \w и думают, что это буквы. На деле это [A-Za-z0-9_]: цифры и подчёркивание остаются, а кириллица вырезается.
Пишут \p{L} без флага u. Ошибки нет: без него \p означает просто букву «p», и регулярка молча делает не то.
Забывают про ё в самописном диапазоне а-я. Слово «ёлка» превращается в «лка», и баг всплывает только на реальных данных.