Введение в регулярные выражения

Введение в регулярные выражения

Технический фундамент regex в JavaScript

Regex в JS это объект RegExp + шаблон + флаги. Практически важно помнить:

  • шаблон может совпадать частично или полностью (в зависимости от ^ и $);
  • флаги (g, i, m и др.) меняют поведение того же шаблона;
  • один и тот же regex по-разному работает в test, match, replace;
  • regex проверяет форму текста, но не бизнес-смысл данных.

Это помогает не воспринимать регулярки как "магическую строку", а видеть в них предсказуемый механизм.

Зачем тебе regex в реальной разработке

Почти в каждом продукте есть текст, который нужно проверять, искать или чистить: email, телефон, хэштег, код купона, URL, имя файла. Делать это только через includes, slice и длинные if быстро становится неудобно. Регулярные выражения (regex) дают компактный язык для описания текстовых шаблонов.

Ключевой момент: regex это не "магическая строка", а формальный шаблон, который описывает, что считать совпадением.

Проверь себя: почему правило "должно начинаться с буквы и содержать только цифры/буквы" неудобно проверять вручную десятком условий?

Что такое регулярное выражение простыми словами

Регулярное выражение это шаблон поиска в строке. В JavaScript его можно задать двумя способами:

  • через литерал: /pattern/flags;
  • через конструктор: new RegExp('pattern', 'flags').
const regex = /cat/;

console.log(regex.test('my cat is here')); // true
console.log(regex.test('my dog is here')); // false

Метод test возвращает true/false: есть совпадение или нет.

Смотри, что важно: regex проверяет шаблон, а не "смысл" текста. Он не понимает контекст так, как человек.

Самые первые метасимволы

Новый термин: метасимвол - специальный символ regex, который имеет особое значение.

На старте запомни два ключевых:

  • . - любой один символ (кроме перевода строки в базовом режиме);
  • \d - любая цифра (0..9).
console.log(/c.t/.test('cat')); // true
console.log(/c.t/.test('cut')); // true
console.log(/\d\d/.test('A7')); // false
console.log(/\d\d/.test('A79')); // true

Здесь часто путаются: . означает "любой символ", а не точку как текстовый знак.

Проверь себя: что покажет /a.b/.test('a-b') и почему?

Флаги regex

Флаги меняют поведение шаблона. На старте чаще всего нужны:

  • i - игнорировать регистр;
  • g - искать все совпадения;
  • m - многострочный режим.
const text = 'JavaScript and javascript';

console.log(/javascript/.test(text)); // false
console.log(/javascript/i.test(text)); // true
console.log(text.match(/javascript/gi)); // ['JavaScript', 'javascript']

Ключевой момент: i влияет на чувствительность к регистру, а g - на количество найденных совпадений.

Смотри, что важно: флаг m (multiline) меняет поведение якорей ^ и $ — они начинают работать не только для всей строки целиком, но и для каждой строки внутри текста (между \n).

const text = 'cat\nmy cat';

console.log(/^cat/.test(text)); // true (совпало только в самом начале всей строки)
console.log(/^cat/m.test(text)); // true (совпадение проверяется для каждой строки)
console.log(/^my/m.test(text)); // true (нашли "my" во 2-й строке)

Базовые сценарии из продукта

  1. Валидация купона.

Шаблон вроде SALE2024 можно проверить regex, чтобы не принимать мусор.

  1. Поиск тегов в тексте.

Например, найти все #слова в пользовательском комментарии.

  1. Фильтр логов.

Отобрать строки с нужным форматом ID.

const couponRegex = /^[A-Z]{4}\d{4}$/;

console.log(couponRegex.test('SALE2024')); // true
console.log(couponRegex.test('sale2024')); // false

Дополнительный пример: создание regex через RegExp из динамического префикса.

const prefix = 'ORD';
const dynamicRegex = new RegExp(`^${prefix}-\\d{5}$`);

console.log(dynamicRegex.test('ORD-12345')); // true
console.log(dynamicRegex.test('INV-12345')); // false

Смотри, что важно: если часть шаблона строится из пользовательской строки, ее нужно экранировать, иначе спецсимволы (., *, +, ? и т.д.) внезапно станут частью regex-логики.

function escapeRegExp(str) {
  return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}

const userPrefix = 'ORD.'; // точка - спецсимвол
const safe = escapeRegExp(userPrefix);
const r = new RegExp(`^${safe}-\\d{5}$`);

console.log(r.test('ORD.-12345')); // true
console.log(r.test('ORDX-12345')); // false

Частые ошибки новичков

  • Забывать экранирование (\) в шаблонах через строку.
  • Путать literal /.../ и строку '...'.
  • Использовать regex для всего подряд, даже где хватает простых методов строк.
  • Не тестировать edge case (пустая строка, пробелы, неожиданные символы).

Анти-провал: если правило очень простое (например, "строка содержит @"), не всегда нужен regex. Выбирай инструмент по задаче.

Что будет, если изменить входные данные

В примере с купоном:

  • SALE2024 проходит;
  • SALE24 не проходит (мало цифр);
  • sale2024 не проходит (неверный регистр);
  • SALE2024 не проходит из-за лишнего пробела.

Так ты получаешь предсказуемый фильтр на входе.

Проверь себя: почему пробел в конце строки может быть критичен для валидации?

Краткий итог

  • Regex это шаблон для поиска и проверки строк.
  • В JavaScript чаще всего стартуют с test, match и флагов i, g.
  • Метасимволы (., \d и другие) задают правила совпадения.
  • Regex особенно полезен для валидации и извлечения данных из текста.
  • Перед использованием всегда проверяй шаблон на edge case, а не только на "идеальный" вход.