$ sudo teach IT
МОДУЛЬ 12 · УРОК 4

Регулярные выражения (RegExp)

Регулярные выражения — это мини-язык для описания текстовых паттернов. С их помощью можно найти все телефонные номера в тексте, проверить правильность email, заменить все упоминания слова — одной строкой кода. Звучит сложно, но разберёмся.

⏱ ~30 минут 🎓 Средний уровень 🔍 RegExp

🔍 Что такое регулярные выражения?

Представьте: у вас есть огромный текст — миллион символов. Вам нужно найти все email-адреса. Как вы это сделаете? Без регулярных выражений — вручную: ищем символ @, смотрим что до него, что после... Десятки строк кода. С регулярными выражениями — одна строка.

Регулярное выражение (Regular Expression, RegExp) — это паттерн (шаблон), описывающий что именно нужно найти в строке. Регулярки — не уникальная фича JavaScript: они работают практически во всех языках программирования и многих текстовых редакторах.

🔑 Регулярное выражение — это описание паттерна. Вы описываете, как выглядит то, что ищете, и JS находит все вхождения в строке.

В JavaScript регулярное выражение создаётся двумя способами:

// Литеральная запись — чаще всего используется
const regex1 = /hello/;

// Через конструктор — когда паттерн динамический
const pattern = "hello";
const regex2 = new RegExp(pattern);

🏁 Флаги регулярных выражений

После закрывающего слеша можно добавить флаги — они меняют поведение поиска:

/паттерн/флаги

/hello/g   // g — глобальный поиск (все совпадения, не только первое)
/hello/i   // i — без учёта регистра (Hello, HELLO, hElLo — всё найдёт)
/hello/m   // m — многострочный режим (^ и $ работают для каждой строки)
/hello/gi  // флаги можно комбинировать
g

Global — найти все совпадения. Без g — только первое.

i

Ignore case — игнорировать регистр. /hello/i найдёт Hello, HELLO, hElLo.

m

Multiline — ^ и $ работают для каждой строки текста, а не только начала/конца всего текста.

s

Dotall — точка . совпадает и с символом новой строки \n.

🧩 Метасимволы — алфавит регулярок

Мощь регулярных выражений — в специальных символах, каждый из которых имеет особый смысл. Запоминайте постепенно — они быстро войдут в привычку:

Классы символов

\d   — одна цифра (0-9). Эквивалент [0-9]
\D   — один НЕ-цифровой символ
\w   — слово-символ: буква, цифра или _ (подчёркивание). [a-zA-Z0-9_]
\W   — не слово-символ (пробел, пунктуация и т.д.)
\s   — пробельный символ (пробел, таб, перенос строки)
\S   — не пробельный символ
.    — любой символ кроме \n (новой строки)

Квантификаторы (сколько раз)

+    — один или более раз (обязательно хотя бы одно)
*    — ноль или более раз (может не быть вообще)
?    — ноль или один раз (опциональный символ)
{n}  — ровно n раз: \d{4} — ровно 4 цифры
{n,} — n или более раз
{n,m}— от n до m раз: \d{2,4} — от 2 до 4 цифр

Позиционные якоря

^    — начало строки
$    — конец строки
\b   — граница слова (между словесным и несловесным символом)

Наборы и группы

[abc]   — один из символов: a, b или c
[a-z]   — один символ из диапазона a-z
[^abc]  — любой символ КРОМЕ a, b, c
(abc)   — группа — запоминает найденное
a|b     — a или b (альтернатива)

🛠️ Методы для работы с RegExp

JavaScript предоставляет несколько методов для работы с регулярными выражениями. Одни — методы RegExp, другие — методы строки:

const text = "Мне 25 лет и я знаю 3 языка программирования";

// test() — проверить: есть ли совпадение? Возвращает true/false
/\d+/.test(text);  // true — есть хотя бы одна цифра

// match() — найти совпадения. Возвращает массив или null
text.match(/\d+/);   // ["25"] — только первое (без флага g)
text.match(/\d+/g);  // ["25", "3"] — все числа (с флагом g)

// search() — позиция первого совпадения или -1
text.search(/\d+/);  // 4 — позиция символа "2"

// replace() — заменить совпадение
text.replace(/\d+/, "##");    // "Мне ## лет и я знаю 3 языка..."
text.replace(/\d+/g, "##");   // "Мне ## лет и я знаю ## языка..."

// split() — разбить строку по паттерну
"один,два;три".split(/[,;]/);  // ["один", "два", "три"]

💡 Метод matchAll() — современная альтернатива match(/g). Возвращает итератор со всеми совпадениями и их позициями. Используется с флагом g обязательно.

🧪 Практические примеры

✉️ Валидация email

function isValidEmail(email) {
  // Упрощённый паттерн email: что-то @ что-то . что-то
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
  return emailRegex.test(email);
}

console.log(isValidEmail("user@example.com"));  // true
console.log(isValidEmail("неверный-email"));    // false
console.log(isValidEmail("a@b.c"));             // true

🔢 Найти все числа в строке

function extractNumbers(text) {
  const matches = text.match(/\d+/g);
  return matches ? matches.map(Number) : [];
}

const sentence = "В 2024 году куплено 3 книги на сумму 1500 рублей";
console.log(extractNumbers(sentence));
// [2024, 3, 1500]

🔄 Замена и форматирование

// Убрать лишние пробелы
const messy = "слишком    много     пробелов";
const clean = messy.replace(/\s+/g, ' ');
console.log(clean); // "слишком много пробелов"

// Форматировать телефон: 79991234567 -> +7 (999) 123-45-67
function formatPhone(phone) {
  return phone.replace(
    /^7(\d{3})(\d{3})(\d{2})(\d{2})$/,
    '+7 ($1) $2-$3-$4'
  );
}
console.log(formatPhone("79991234567")); // +7 (999) 123-45-67

🏷️ Найти все хэштеги

const post = "Учусь #JavaScript и #программирование — это #классно!";
const hashtags = post.match(/#\w+/g);
console.log(hashtags);
// ["#JavaScript", "#программирование", "#классно"]

⚠️ Советы и частые ошибки

🔸 Экранирование точки: в регулярках точка . означает «любой символ». Если хотите найти именно точку — экранируйте: \.

🔸 Жадные vs ленивые квантификаторы: + и * жадные — захватывают как можно больше. Добавьте ? чтобы сделать ленивыми: +? захватит как можно меньше.

✅ Инструмент для проверки: сайт regex101.com — отличный визуальный отладчик регулярных выражений. Вставьте паттерн и тестовую строку — увидите все совпадения с объяснениями.

// Жадный vs ленивый
const html = "жирный и ещё жирный";

html.match(/.+<\/b>/)[0];   // "жирный и ещё жирный" — жадный!
html.match(/.+?<\/b>/)[0];  // "жирный" — ленивый, берёт минимум

✅ Итоги урока

  • Регулярное выражение — паттерн для поиска, проверки и замены текста
  • Создаётся как /паттерн/флаги или через new RegExp()
  • Флаги: g (все совпадения), i (без учёта регистра), m (многострочный)
  • \d — цифра, \w — буква/цифра/_, \s — пробел, . — любой символ
  • Квантификаторы: + (1+), * (0+), ? (0 или 1), {n,m} (от n до m)
  • Якоря: ^ — начало, $ — конец, \b — граница слова
  • Методы: test(), match(), replace(), split(), search()

Следующий урок — объект Date: как работать с датами и временем в JavaScript. 📅

Тест: Регулярные выражения

7 вопросов

Валидация email

Реализуйте функцию isValidEmail(email), которая проверяет, является ли строка email-адресом. Используйте регулярное выражение: строка должна содержать символ @ с символами до и после него, и точку после @.

Извлечение чисел из строки

Реализуйте функцию extractNumbers(text), которая принимает строку и возвращает массив всех чисел (целых), найденных в этой строке. Используйте match с регулярным выражением и преобразуйте результат в числа.