Регулярные выражения
Атрибут pattern
<input type="text" pattern="\D+" title="любые символы кроме чисел">
Пример выше позволяет вводить в текстовое поле любое количество не цифр. Если ввести данные, не подходящие под условия pattern, отправка данных на сервер будет блокирована, а поле выдаст подсказку.
Однако, не всегда можно коротко описать регулярное выражение, поэтому при использовании pattern стоит придерживаться максимально простых правил, подсказку для которых можно дополнительно описать с помощью атрибутов title
и placeholder
.
<input type="text" name="passport" placeholder="00 00 №000000" pattern="\d{2}\s*\d{2}\s*№?\d{6}">
Методы JavaScript для работы с регулярными выражениями
'Ехали медведи на велосипеде'.split(/\s+/); // ['Ехали', 'медведи', 'на', 'велосипеде']
'Florence__+__The_Machine_-_Spectrum'.replace(/_+/g, ' '); // Florence + The Machine - Spectrum
'Потому что ты медведь...'.search(/медведь/); // 14
/-/.test('Жизнь - туман!'); // true
Справочник
const regex = /выражение/модификатор;
или
const regex = new RegExp('выражение', 'модификатор');
Специальные символы
Символьные селекторы (наборы символов)
Селектор | Описание | EcmaScript |
---|---|---|
[] | последовательность символов | |
[^] | отрицание последовательности символов | |
[0-9] | любая цифра от 0 до 9 | |
[1-8] | любая цифра от 1 до 8 | |
[а-яё] | любая буква русского алфавита в нижнем регистре | |
[а-яёА-ЯЁ] | любая буква русского алфавита в нижнем и верхнем регистре | |
[а-яёА-ЯЁa-zA-Z] | любая буква русского или английского алфавита в нижнем и верхнем регистре | |
[D-Q] | буква английского алфавита в верхнем регистре между D и Q | |
[^.,:;?!-] | не знаки препинания | |
\u{ХХХХ} | XXXX шестнадцатеричный код юникод символа | 2018 |
Символьные селекторы (классы)
Селектор | Эквивалент | Описание | EcmaScript |
---|---|---|---|
\d | [0-9] | цифры | |
\w | [a-zA-Z0-9] | латинские буквы, цифры и символ подчёркивания | |
\s | [ \n\r\t\] | пробельные символы | |
. | кроме \n | любой символ, кроме перевода строки | |
\p{имя} | — | управляющая последовательность символов | 2018 |
Символьные отрицающие селекторы
Селектор | Эквивалент | Описание | EcmaScript |
---|---|---|---|
\D | [^0-9] | не цифры | |
\W | [^a-zA-Z0-9] | не латинские буквы, цифры и символ подчёркивания | |
\S | [^ \n\r\t\] | не пробельные символы | |
\P{имя} | — | не управляющая последовательность символов | 2018 |
Селекторы непечатных символов
Селектор | Описание |
---|---|
\n | перевод строки |
\r | возврат каретки |
\t | символ табуляции |
\v | символ вертикальной табуляции |
\b | граница слова (только латиница) |
\B | не граница слова |
^ | начало строки |
$ | конец строки |
Квантификаторы
Квантификатор | Эквивалент | Описание | Жадность |
---|---|---|---|
{n} | — | совпадение с точным количеством, где n — число | — |
{min,max} | — | совпадение в диапазоне от минимального до максимального значения | жадный |
{min,max}? | — | совпадение в диапазоне от минимального до максимального значения | ленивый |
{min,} | — | совпадение в диапазоне от минимального до бесконечности | жадный |
+ | {1,} | один или бесконечное множество совпадений | жадный |
* | {0,} | ни одного или бесконечное множество совпадений | жадный |
? | {0,1} | одно или ни одного совпадения | — |
+? | {1,}? | один или бесконечное множество совпадений | ленивый |
*? | {0,}? | ни одного или бесконечное множество совпадений | ленивый |
Скобки
Конструкция | Описание | EcmaScript |
---|---|---|
() | сохранение и группировка | |
(?:) | группировка без сохранения | |
(a|b|c) | условие ИЛИ: a или b или c | |
(a|b|)c | условие ИЛИ с пустым значением: ac или bc или c | |
x(?=y) | опережающая проверка (найдёт x , справа от которого есть y ) | |
x(?!y) | негативная опережающая проверка (найдёт x , справа от которого нет y ) | |
(?<=y)x | ретроспективная проверка (найдёт x , слева от которого есть y ) | 2018 |
(?<!y)x | негативная ретроспективная проверка (найдёт x , слева от которого нет y ) | 2018 |
(?<имя>) | именованное сохранение | 2018 |
Модификаторы (флаги)
Модификатор | Описание | EcmaScript |
---|---|---|
g | искать все совпадения | |
i | не учитывать регистр | |
m | многострочный режим (. совпадает с \n ) | |
u | поддержка юникод символов | 2015 |
y | «липкий» поиск, основанный на позиции lastIndex | 2015 |
s | dotAll — селектор . совпадает с \n | 2018 |
Экранирование
\
— символ экранирования
^ | $ ( ) [ ] { } . + * ? \
— символы, требующие экранирования
Примеры
Валидируем хэштеги
const inputHashtag = document.querySelector('#hashtags');
const errorMessage = `Неверный формат хэштегов`;
const onHashtagInput = (evt) => {
evt.target.setCustomValidity(/^\s*(?:(#[a-zа-яё0-9]{1,19})(?:\s+(?!.*?\1\s?)|$)?){1,5}$/i.test(evt.target.value) ? '' : errorMessage);
evt.target.reportValidity();
};
inputHashtag.addEventListener('input', onHashtagInput);
- Регулярное выражение задействует всю строку от начала ^ и до конца $.
- Перед хэштегами могут быть, а могут не быть пробельные символы \s*.
- Первые скобки, не сохраняющие (?:), нужны для обобщения хэштега с пробельными символами \s+ и концом строки, а также для проверки количества хэштегов 5.
- Первые сохраняющие скобки (#[a-zа-яё0-9]19) проверяют написание хэштега, наличие # и длину 20 знаков.
- Следующие за ними не сохраняющие скобки (?:\s+(?!.?\1\s?)|$) являются условием, где сначала проверяется наличие пробелов после хэштега и выполняется опережающая проверка на совпадение с сохранённым состоянием первых скобок (?!.?\1\s?) или с концом строки $.
- Так как регулярное выражение использует нечувствительный к регистру модификатор i, то и сохранённые состояния тоже не чувствительны к регистру, любые хэштеги #a и #A будут считаться не валидными.
ФИО
У нас есть поле с фамилией, именем и отчеством на русском языке. Давайте допишем паттерн, который предотвратит отправку на сервер недопустимых символов, а затем проверим, все ли три части ФИО присутствуют в строке, а если нет, выведем сообщение «Неверный формат данных».
При выборе имени ребенка не допускается использование цифр, буквенно-цифровых обозначений и символов, не являющихся буквами, за исключением знака «дефис».
<input type="text" name="full_name" placeholder="фамилия имя отчество" pattern="[-а-яёА-ЯЁ ]+">
const MAX_PARTS = 3;
const inputElement = document.querySelector('input[name=full_name]');
const parts = inputElement.value.split(/\s+/, MAX_PARTS);
inputElement.addEventListener('input', () => {
inputElement.setCustomValidity('');
const parts = inputElement.value.split(/\s+/, MAX_PARTS);
if (parts.length < MAX_PARTS) {
inputElement.setCustomValidity('Неверный формат данных');
}
});
Валидация идентификаторов тегов
const elements = document.querySelectorAll('*');
elements.forEach((element) => {
if (element.id !== '' && /^[^a-zA-Z]/.test(element.id)) {
alert(`Elements id="${element.id}" is wrong!`);
}
});
:)))) -> :)
const comments = [
{
name: `Вера`,
comment: `Фильм укатайка :)))))))))))))))))))`
},
{
name: `Даниил`,
comment: `Были смешные моменты :), но в целом такое...`
},
{
name: `DarkLord`,
comment: `:)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))`
}
];
comments.forEach((item, i) => {
item.comment = item.comment.replace(/:\)+/g, ':)');
});
console.log(comments);
trimChars
const trimChars = (str, chars = '\\s') => {
if (!str) {
return str;
}
return str.replace(new RegExp(`^[${chars}]+|[${chars}]+$`, 'g'), '');
};
console.log(trimChars('"Однажды, в студёную зимнюю пору..."', '"')); // Однажды, в студёную зимнюю пору...
console.log(trimChars('**_Роднит людей космическая сопричастность_**', '*_')); // Роднит людей космическая сопричастность
console.log(trimChars(' Привет! ')); // Привет!