Перейти к содержанию
  • Лента
  • Категории
  • Последние
  • Метки
  • Популярные
  • Пользователи
  • Группы
Свернуть
exlends
Категории
  1. Главная
  2. Категории
  3. Языки программирования
  4. JavaScript
  5. Регулярные выражения в JavaScript: Полный гайд и шпаргалка

Регулярные выражения в JavaScript: Полный гайд и шпаргалка

Запланировано Прикреплена Закрыта Перенесена JavaScript
1 Сообщения 1 Постеры 38 Просмотры
  • Сначала старые
  • Сначала новые
  • По количеству голосов
Ответить
  • Ответить, создав новую тему
Авторизуйтесь, чтобы ответить
Эта тема была удалена. Только пользователи с правом управления темами могут её видеть.
  • AladdinA Не в сети
    AladdinA Не в сети
    Aladdin
    js
    написал отредактировано
    #1

    Зачем нужны регулярные выражения?

    Регулярные выражения (regex) — это мощный инструмент для поиска, проверки и преобразования текста по определённым шаблонам. Без них разработчику пришлось бы писать громоздкий код с множеством условий.

    Примеры использования:

    • Валидация email, номеров телефонов, URL
    • Поиск и замена текста по шаблону
    • Парсинг и извлечение данных из строк
    • Обработка лог-файлов
    • Форматирование данных

    Быстрый пример:

    // Без regex — много условий и цикловых конструкций
    // Валидация email вручную — сложно и ненадёжно
    
    // С regex — одна строка
    const isValidEmail = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
    

    Основы: Как создать регулярное выражение

    Два способа создания

    1. Литеральная нотация (предпочтительно для статичных паттернов)

    const pattern = /hello/;
    

    2. Конструктор RegExp (для динамических паттернов)

    const pattern = new RegExp('hello');
    const userPattern = new RegExp(`${userInput}`, 'gi');
    

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


    Флаги: Управление поведением

    Флаги добавляются после паттерна и изменяют способ поиска:

    Флаг Описание Пример
    g Global — найти все совпадения, не только первое /cat/g находит все “cat” в строке
    i Ignore case — игнорировать регистр /hello/i найдёт “Hello”, “HELLO”, “hello”
    m Multiline — ^ и $ работают для каждой строки /^start/m найдёт “start” в начале каждой строки
    s Dotall — точка . будет совпадать с переносом строки /a.b/s найдёт “a\nb”
    u Unicode — правильная работа с Unicode символами /\p{L}/u найдёт любую букву
    d Indices — получить позиции совпадений использует свойство indices

    Комбинирование флагов:

    const pattern = /hello/gi; // Глобальный поиск, игнорируя регистр
    const str = 'Hello there, HELLO world';
    console.log(str.match(pattern)); // ['Hello', 'HELLO']
    

    Символы и классы: Что искать

    Простые символы

    /abc/.test('abc');        // true — ищем точную последовательность
    /abc/.test('abcd');       // true — "abc" есть в строке
    /abc/.test('ab c');       // false — нет точной последовательности
    

    Специальные символы (метасимволы)

    Символ Значение Пример
    . Любой символ (кроме переноса строки) /a.c/ совпадает с “abc”, “adc”, но не “a\nc”
    ^ Начало строки /^hello/ только если строка начинается с “hello”
    $ Конец строки /world$/ только если строка заканчивается на “world”
    \ Экранирование специального символа /a\.b/ ищет букв “a”, точку и “b” буквально

    Примеры:

    // Начало и конец строки
    /^hello/.test('hello world');        // true
    /^hello/.test('say hello');          // false
    /world$/.test('hello world');        // true
    
    // Точка — любой символ
    /a.c/.test('abc');                   // true
    /a.c/.test('adc');                   // true
    /a.c/.test('a\nc');                  // false (нужен флаг 's')
    

    Классы символов: [...] — выбор из набора

    Квадратные скобки означают “любой один символ из списка”:

    // Одиночные символы
    /[aeiou]/.test('hello');             // true (буква 'e')
    /[0-9]/.test('abc123');              // true (цифра '1')
    
    // Диапазоны
    /[a-z]/.test('hello');               // true (любая строчная буква)
    /[A-Z]/.test('Hello');               // true (прописная буква)
    /[0-9]/.test('test2');               // true (цифра)
    
    // Инверсия (всё кроме указанного)
    /[^aeiou]/.test('hello');            // true (согласная буква)
    

    Встроенные классы: Сокращения для популярных наборов

    Класс Эквивалент Описание
    \d [0-9] Цифра
    \D [^0-9] Не цифра
    \w [A-Za-z0-9_] Буква, цифра или подчёркивание (word character)
    \W [^A-Za-z0-9_] Не буква/цифра
    \s [ \t\n\r\f] Пробел или табуляция
    \S [^ \t\n\r\f] Не пробел
    \b — Граница слова (между буквой и не-буквой)
    \B — Не граница слова

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

    // Найти все цифры в строке
    'abc123def456'.match(/\d/g);         // ['1', '2', '3', '4', '5', '6']
    
    // Найти все слова
    'hello world 123'.match(/\w+/g);     // ['hello', 'world', '123']
    
    // Пробелы
    'hello   world'.split(/\s+/);        // ['hello', 'world']
    
    // Только в начале слова
    'par spar apart'.replace(/\bpar/g, 'X'); // 'X spar aX' — заменяет только целые слова
    

    Квантификаторы: Количество повторений

    Квантификаторы указывают, сколько раз должен повториться предыдущий символ или группа:

    Квантификатор Значение Пример
    ? 0 или 1 раз (опционально) /colou?r/ совпадает с “color” и “colour”
    * 0 или больше раз /ab*c/ совпадает с “ac”, “abc”, “abbc”
    + 1 или больше раз /ab+c/ совпадает с “abc”, “abbc”, но не “ac”
    {n} Точно n раз /a{3}/ совпадает только с “aaa”
    {n,} n или больше раз /a{2,}/ совпадает с “aa”, “aaa”, “aaaa”
    {n,m} От n до m раз /a{2,4}/ совпадает с “aa”, “aaa” или “aaaa”

    Примеры:

    // Опциональные символы
    const phonePattern = /\d{3}-?\d{3}-?\d{4}/;
    phonePattern.test('123-456-7890');   // true
    phonePattern.test('1234567890');     // true
    
    // Пароль: минимум 8 символов
    /^.{8,}$/.test('mypass123');         // true
    
    // Телефон США
    /^\(?[0-9]{3}\)?[-. ]?[0-9]{3}[-. ]?[0-9]{4}$/.test('(123) 456-7890'); // true
    
    // Одна или больше цифр
    '123abc456'.match(/\d+/g);           // ['123', '456']
    

    Группы и захват: Выделение части совпадения

    Группы для логики

    // Группа группирует для квантификаторов
    /(ab)+/.test('ababab');              // true
    /(ab)+/.test('abac');                // false
    
    // Или внутри группы
    /(cat|dog)/.test('I have a cat');    // true
    /col(ou)?r/.test('color');           // true
    /col(ou)?r/.test('colour');          // true
    

    Захватывающие группы: Извлечение данных

    Скобки () создают “захватывающую группу” — часть совпадения, которую потом можно использовать:

    // Извлечение частей совпадения
    const email = 'john@example.com';
    const match = email.match(/([a-z]+)@([a-z.]+)/);
    
    console.log(match[0]);  // 'john@example.com' (полное совпадение)
    console.log(match[1]);  // 'john' (первая группа)
    console.log(match[2]);  // 'example.com' (вторая группа)
    
    // В replace — используем группы через $1, $2 и т.д.
    'John Smith'.replace(/(\w+) (\w+)/, '$2, $1'); // 'Smith, John'
    
    // Дата: преобразование из YYYY-MM-DD в DD.MM.YYYY
    '2025-01-15'.replace(/(\d{4})-(\d{2})-(\d{2})/, '$3.$2.$1'); // '15.01.2025'
    

    Неzахватывающие группы: (?:...)

    Когда нужна группа для логики, но не нужно сохранять совпадение:

    // С захватом (создаёт группу 1)
    /(cat|dog) \1/.test('cat cat');      // true (говорит: повторить то же слово)
    
    // Без захвата — просто группировка
    const color = /(red|green|blue)/;
    const result = 'I like green'.match(color);
    console.log(result[1]); // 'green'
    
    // Когда захват не нужен
    /(?:https?|ftp):\/\//.test('https://example.com'); // true
    'files.txt, images.png'.match(/\.(?:txt|png|jpg)/g); // ['.txt', '.png']
    

    Именованные группы: Читаемость кода

    const datePattern = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
    const date = '2025-01-15';
    const match = date.match(datePattern);
    
    console.log(match.groups.year);  // '2025'
    console.log(match.groups.month); // '01'
    console.log(match.groups.day);   // '15'
    
    // В replace используем $<name>
    '2025-01-15'.replace(datePattern, '$<day>.$<month>.$<year>'); // '15.01.2025'
    

    Backreference: Ссылка на уже найденное

    Backreference \1, \2 и т.д. означают “повтори то же, что нашли в группе 1, 2 и т.д.”:

    // Найти повторяющиеся слова
    /\b(\w+) \1\b/.test('the the');      // true
    /\b(\w+) \1\b/.test('the cat');      // false
    
    // Убрать повторяющиеся слова
    'hello hello world world test'.replace(/\b(\w+) \1+\b/g, '$1');
    // 'hello world test'
    
    // Фигурные скобки: найти две одинаковые цифры подряд
    /(\d)\1/.test('11');                 // true
    /(\d)\1/.test('12');                 // false
    
    // Скобки вокруг одного и того же
    /([([]))\1/.test('(())');            // true
    

    Lookahead и Lookbehind: Условные совпадения

    Lookahead и lookbehind — это “нулевой ширины” проверки. Они проверяют, есть ли что-то дальше или раньше, но не включают это в совпадение.

    Positive lookahead (?=...)

    “Совпадает, если дальше идёт…”

    // Найти цифры, которые идут перед словом "miles"
    '5 miles, 10 kilometers'.match(/\d+(?= miles)/g); // ['5']
    
    // Пароль содержит минимум одну цифру
    /(?=.*\d)/.test('password123');      // true (дальше идут цифры)
    /(?=.*\d)/.test('password');         // false
    
    // Числа перед запятой или концом
    '5, 10, 15'.match(/\d+(?=[,]|$)/g); // ['5', '10', '15']
    

    Negative lookahead (?!...)

    “Совпадает, если дальше НЕ идёт…”

    // Найти "cat", которые НЕ следуют перед цифрой
    'cat, cat1, cat2'.match(/cat(?!\d)/g); // ['cat']
    
    // Слова, не являющиеся числами
    'hello 123 world'.match(/\w+(?!\d)/g); // ['hello', 'world']
    
    // URL без https
    'http://example.com, https://secure.com'.match(/https?:\/\/(?!https)/g);
    

    Positive lookbehind (?<=...)

    “Совпадает, если перед этим идёт…”

    // Цифры, которые идут после доллара
    '$5, €10, $20'.match(/(?<=\$)\d+/g); // ['5', '20']
    
    // Слово, которому предшествует точка
    'Dr. Smith'.match(/(?<=\.)[\w\s]+/);  // [' Smith']
    

    Negative lookbehind (?<!...)

    “Совпадает, если перед этим НЕ идёт…”

    // Слова, которым НЕ предшествует двоеточие
    'name: John, age: 25, city: Moscow'.match(/(?<!:)\s(\w+)/g);
    
    // Цены без валюты
    '$10 free! €20 paid'.match(/(?<!\$)\d+/g); // ['20'] в контексте
    

    Практический пример с lookaround:

    // Валидация пароля: минимум 8 символов, буква и цифра
    const passwordRegex = /^(?=.*[a-zA-Z])(?=.*\d).{8,}$/;
    passwordRegex.test('password1');     // true
    passwordRegex.test('password');      // false (нет цифры)
    passwordRegex.test('pass1');         // false (меньше 8)
    

    Методы работы с regex в JavaScript

    test() — Проверка на совпадение

    Возвращает true или false:

    const pattern = /hello/;
    pattern.test('hello world');         // true
    pattern.test('goodbye world');       // false
    

    match() — Найти все совпадения

    Возвращает массив совпадений или null:

    // Без флага 'g' — только первое совпадение с деталями
    'hello hello hello'.match(/hello/);
    // ['hello', index: 0, groups: undefined, input: 'hello hello hello']
    
    // С флагом 'g' — все совпадения, но без деталей
    'hello hello hello'.match(/hello/g);
    // ['hello', 'hello', 'hello']
    
    // С группами
    'john@example.com jane@test.com'.match(/(\w+)@(\w+)/g);
    // ['john@example.com', 'jane@test.com']
    

    matchAll() — Итератор по всем совпадениям

    const str = 'test1 test2 test3';
    const pattern = /test(\d)/g;
    const matches = Array.from(str.matchAll(pattern));
    
    matches.forEach(match => {
      console.log(match[0]);  // полное совпадение
      console.log(match[1]);  // первая группа
      console.log(match.index); // позиция
    });
    

    search() — Позиция первого совпадения

    Возвращает индекс или -1:

    'hello world'.search(/world/);       // 6
    'hello world'.search(/xyz/);         // -1
    

    replace() — Заменить первое совпадение

    'hello hello'.replace(/hello/, 'hi');        // 'hi hello'
    'hello hello'.replace(/hello/g, 'hi');      // 'hi hi'
    
    // С функцией-обработчиком
    '5 and 10'.replace(/\d+/g, (match) => {
      return parseInt(match) * 2;
    });
    // '10 and 20'
    

    replaceAll() — Заменить все совпадения

    'hello hello'.replaceAll('hello', 'hi');    // 'hi hi'
    // Эквивалент: replace(/hello/g, 'hi')
    

    split() — Разбить строку по паттерну

    // Разделитель
    'a,b;c:d'.split(/[,;:]/);           // ['a', 'b', 'c', 'd']
    
    // С захватывающими группами — включить разделители
    'a1b2c3'.split(/(\d)/);             // ['a', '1', 'b', '2', 'c', '3']
    
    // Множественные пробелы
    'hello    world  test'.split(/\s+/); // ['hello', 'world', 'test']
    

    exec() — Детальный поиск

    Возвращает подробный результат или null:

    const pattern = /(\d{3})-(\d{3})-(\d{4})/;
    const match = pattern.exec('My phone: 555-123-4567');
    
    match[0];    // '555-123-4567' (полное совпадение)
    match[1];    // '555' (первая группа)
    match[2];    // '123'
    match[3];    // '4567'
    match.index; // 10 (где начинается совпадение)
    

    Практические примеры из реальной жизни

    Валидация email

    const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    emailPattern.test('user@example.com');      // true
    emailPattern.test('invalid.email@');        // false
    

    Валидация телефона

    // Формат: (XXX) XXX-XXXX или XXX-XXX-XXXX
    const phonePattern = /^(\+1)?[-.\s]?\(?[0-9]{3}\)?[-.\s]?[0-9]{3}[-.\s]?[0-9]{4}$/;
    phonePattern.test('(555) 123-4567');       // true
    phonePattern.test('555-123-4567');         // true
    phonePattern.test('+1-555-123-4567');      // true
    

    Извлечение всех URL из текста

    const text = 'Visit https://example.com and http://test.org';
    const urls = text.match(/https?:\/\/[^\s]+/g);
    // ['https://example.com', 'http://test.org']
    

    Парсинг даты и преобразование формата

    // ISO (YYYY-MM-DD) в локальный (DD.MM.YYYY)
    '2025-01-15 2025-12-25'.replace(/(\d{4})-(\d{2})-(\d{2})/g, '$3.$2.$1');
    // '15.01.2025 25.12.2025'
    

    Удаление HTML тегов

    const html = '<p>Hello <b>world</b>!</p>';
    html.replace(/<[^>]*>/g, '');               // 'Hello world!'
    

    Каждое слово с заглавной буквы (Title Case)

    function titleCase(str) {
      return str.replace(/\b\w/g, (match) => match.toUpperCase());
    }
    titleCase('hello world javascript'); // 'Hello World Javascript'
    

    Форматирование цены (добавление разделителей)

    const price = '1000000';
    price.replace(/\B(?=(\d{3})+(?!\d))/g, ' '); // '1 000 000'
    // Или: price.replace(/(\d)(?=(\d{3})+$)/g, '$1 '); // '1 000 000'
    

    Валидация пароля (сложный пример)

    // Минимум 8 символов, минимум одна буква, одна цифра, один спецсимвол
    const passwordPattern = /^(?=.*[a-zA-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/;
    
    passwordPattern.test('Pass123!');           // true
    passwordPattern.test('password');           // false (нет цифры и спецсимвола)
    passwordPattern.test('Pass1');              // false (меньше 8 символов)
    

    Замена значений в объекте

    const config = 'name=john&age=25&city=moscow';
    config.replace(/([^=&]+)=([^&]*)/g, (match, key, value) => {
      console.log(`${key}: ${value}`);
      return match;
    });
    // name: john
    // age: 25
    // city: moscow
    

    Частые ошибки и как их избежать

    1. Забыли флаг g — заменилось только первое совпадение

    // ❌ Неправильно
    'hello hello'.replace(/hello/, 'hi');       // 'hi hello'
    
    // ✅ Правильно
    'hello hello'.replace(/hello/g, 'hi');      // 'hi hi'
    

    2. Не экранировали спецсимволы

    // ❌ Неправильно — точка совпадает с любым символом
    /a.b/.test('a b');                  // true (нежелательно)
    
    // ✅ Правильно
    /a\.b/.test('a.b');                 // true
    /a\.b/.test('a b');                 // false
    

    3. Забыли ^ и $ — совпадение может быть частью строки

    // ❌ Неправильно
    /^[0-9]+$/.test('abc123def');       // false (но хотели false)
    /[0-9]+/.test('abc123def');         // true (число есть, но не только число)
    
    // ✅ Правильно
    /^\d+$/.test('123');                // true (только цифры)
    /^\d+$/.test('123abc');             // false (есть буквы)
    

    4. Жадные квантификаторы вместо ленивых

    // ❌ Жадное — захватывает слишком много
    '<p>Hello</p> <b>Bold</b>'.match(/<.*>/g);
    // ['<p>Hello</p> <b>Bold</b>'] — одно совпадение вместо двух
    
    // ✅ Ленивое — `?` после квантификатора
    '<p>Hello</p> <b>Bold</b>'.match(/<.*?>/g);
    // ['<p>', '</p>', '<b>', '</b>'] — правильно
    

    5. Забыли экранировать обратный слэш в конструкторе

    // ❌ Неправильно
    new RegExp('\d+');                  // Интерпретируется неправильно
    
    // ✅ Правильно
    new RegExp('\\d+');                 // Экранируем слэш в строке
    // Или просто используйте литеральную нотацию:
    /\d+/;
    

    Шпаргалка: Визуальный справочник

    Краткая таблица символов

    Что нужно Регулярное выражение Пример
    Любой символ . a.c совпадает “abc”, “adc”
    Буква [a-zA-Z] или \p{L} (с флагом u) [a-z] совпадает “a” до “z”
    Цифра \d \d{3} совпадает “123”
    Не цифра \D \D+ совпадает “abc”
    Пробел \s \s+ совпадает " "
    Не пробел \S \S+ совпадает “word”
    Слово \w \w+ совпадает “hello_123”
    Граница слова \b \bhello\b только целое слово
    Начало ^ ^hello только в начале
    Конец $ world$ только в конце

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

    a?      — ноль или один раз
    a*      — ноль или больше
    a+      — один или больше
    a{3}    — ровно 3 раза
    a{2,5}  — от 2 до 5 раз
    a{2,}   — минимум 2 раза
    a??     — ноль или один (ленивый)
    a*?     — ноль или больше (ленивый)
    a+?     — один или больше (ленивый)
    

    Методы String

    str.test(regex)         → true/false
    str.match(regex)        → [совпадения]
    str.search(regex)       → индекс или -1
    str.replace(regex, new) → новая строка
    str.split(regex)        → массив
    str.matchAll(regex)     → итератор
    

    Интерактивные инструменты и отладка

    При разработке сложных regex используйте онлайн-инструменты:

    • regex101.com — визуализация совпадений с объяснениями
    • regexper.com — диаграмма паттерна
    • regexpal.com — простой тестер

    Совет: Стройте regex пошагово. Сначала простой паттерн, потом добавляйте сложность и тестируйте после каждого шага.


    Заключение

    Регулярные выражения — это мощный инструмент, который экономит время и код. Начните с простых паттернов и постепенно усложняйте. Благодаря lookahead, lookaround и группам, можно решать сложные задачи парсинга и валидации в одной строке.

    Помните: лучший regex — это тот, который легко читать. Используйте именованные группы, комментарии в коде и тестируйте на реальных данных.

    1 ответ Последний ответ
    1

    Категории

    • Главная
    • Новости
    • Фронтенд
    • Бекенд
    • Языки программирования

    Контакты

    • Сотрудничество
    • info@exlends.com
    • Наш чат
    • Наш ТГ канал

    © 2024 - 2025 ExLends, Inc. Все права защищены.

    Политика конфиденциальности
    • Войти

    • Нет учётной записи? Зарегистрироваться

    • Войдите или зарегистрируйтесь для поиска.
    • Первое сообщение
      Последнее сообщение
    0
    • Лента
    • Категории
    • Последние
    • Метки
    • Популярные
    • Пользователи
    • Группы