Регулярные выражения в TypeScript: от теории к практике
Регулярные выражения (regexp или regex) — это мощный инструмент для поиска, замены и проверки строк по заданному шаблону. В TypeScript, как и в JavaScript, регулярные выражения являются встроенной возможностью языка. Эта статья поможет вам освоить синтаксис, научиться применять regex на практике и избежать типичных ошибок.
Что такое регулярное выражение и как его создать в TypeScript
Регулярное выражение — это последовательность символов, которая описывает шаблон поиска. В TypeScript существует два способа создания регулярного выражения:
- Литеральный синтаксис:
/шаблон/флаги - Конструктор RegExp:
new RegExp('шаблон', 'флаги')
Первый способ удобен для статических шаблонов, второй — когда шаблон формируется динамически.
// Литеральный синтаксис
const emailPattern: RegExp = /^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/;
// Конструктор RegExp
const dynamicPattern: string = "hello";
const regexFromString: RegExp = new RegExp(dynamicPattern, "gi");
console.log(emailPattern.test("test@example.com")); // true
console.log(regexFromString.test("Hello world")); // true
Основные методы работы с регулярными выражениями
В TypeScript доступны три ключевых метода для работы с regex. Рассмотрим каждый из них на примерах.
Метод test() — проверка на соответствие
Возвращает true или false. Идеален для валидации.
const hasNumber: RegExp = /\d+/;
console.log(hasNumber.test("abc123")); // true
console.log(hasNumber.test("abc")); // false
Метод exec() — поиск с деталями
Возвращает массив с совпадением и дополнительной информацией (индекс, исходная строка). При использовании флага g запоминает позицию последнего совпадения.
const wordPattern: RegExp = /(\w+)\s(\w+)/;
const result = wordPattern.exec("Hello TypeScript");
if (result) {
console.log(`Полное совпадение: ${result[0]}`); // Hello TypeScript
console.log(`Первая группа: ${result[1]}`); // Hello
console.log(`Вторая группа: ${result[2]}`); // TypeScript
console.log(`Индекс: ${result.index}`); // 0
}
Метод match() — поиск всех совпадений
Вызывается на строке, а не на регулярном выражении. С флагом g возвращает массив всех совпадений.
const text: string = "Цена: 100 руб, скидка: 20 руб";
const prices: RegExp = /\d+/g;
const foundPrices: string[] | null = text.match(prices);
console.log(foundPrices); // ['100', '20', '0']
Синтаксис и часто используемые символы
Чтобы писать эффективные регулярные выражения, нужно знать базовые символы и их значения.
.— любой символ, кроме перевода строки\d— цифра (эквивалент[0-9])\w— буква, цифра или подчёркивание ([a-zA-Z0-9_])\s— любой пробельный символ (пробел, табуляция, новая строка)^— начало строки$— конец строки*— 0 или более повторений+— 1 или более повторений?— 0 или 1 повторение (делает квантификатор ленивым)[]— набор символов (например,[a-z]— все строчные буквы)()— группа захвата|— логическое ИЛИ
// Примеры использования символов
const phonePattern: RegExp = /^\+?7?\d{10}$/;
console.log(phonePattern.test("+79161234567")); // true
const datePattern: RegExp = /^\d{2}\.\d{2}\.\d{4}$/;
console.log(datePattern.test("31.12.2023")); // true
const wordOrNumber: RegExp = /(слово|\d+)/;
console.log(wordOrNumber.test("123")); // true
console.log(wordOrNumber.test("слово")); // true
Практические примеры для реальных задач
Рассмотрим несколько типовых сценариев, где регулярные выражения в TypeScript незаменимы.
Валидация email-адреса
function isValidEmail(email: string): boolean {
const emailRegex: RegExp = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
return emailRegex.test(email);
}
console.log(isValidEmail("user@example.com")); // true
console.log(isValidEmail("invalid-email")); // false
console.log(isValidEmail("user@.com")); // false
Извлечение чисел из строки
function extractNumbers(text: string): number[] {
const numberRegex: RegExp = /\d+/g;
const matches: string[] | null = text.match(numberRegex);
return matches ? matches.map(Number) : [];
}
const logEntry: string = "Ошибка 404 на странице /users/123";
console.log(extractNumbers(logEntry)); // [404, 123]
Замена текста с использованием групп
function formatPhone(phone: string): string {
const phoneRegex: RegExp = /(\d{3})(\d{3})(\d{2})(\d{2})/;
return phone.replace(phoneRegex, "+7 ($1) $2-$3-$4");
}
const rawPhone: string = "9123456789";
console.log(formatPhone(rawPhone)); // +7 (912) 345-67-89
Проверка сложности пароля
function isStrongPassword(password: string): boolean {
const minLength: RegExp = /.{8,}/;
const hasUpperCase: RegExp = /[A-Z]/;
const hasLowerCase: RegExp = /[a-z]/;
const hasDigit: RegExp = /\d/;
const hasSpecial: RegExp = /[!@#$%^&*(),.?":{}|<>]/;
return (
minLength.test(password