0Pricing
C++ Academy · Урок

Группы захвата

Извлекайте совпавшие части

«Группы захвата» — бесплатный урок C++ Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения C++ Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс C++ Academy содержит 4 уроков всего.

Что такое группа захвата?

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

  • (\\d+) захватывает последовательность цифр.
  • Результаты помещаются в std::smatch.
#include <iostream>
#include <regex>

int main() {
    std::regex p("(\\d+)");
    std::smatch m;
    std::string s = "order 42";
    if (std::regex_search(s, m, p)) {
        std::cout << "Captured: " << m[1] << '\n';
    }
    return 0;
}

Результат smatch

std::smatch хранит результаты сопоставления. Индекс [0] содержит всё соответствие, а [1], [2] и последующие — группы захвата по порядку.

#include <iostream>
#include <regex>

int main() {
    std::regex p("(\\w+)@(\\w+)");
    std::smatch m;
    std::string s = "user@host";
    if (std::regex_search(s, m, p)) {
        std::cout << "Whole: " << m[0] << '\n';
        std::cout << "User: " << m[1] << ", Host: " << m[2] << '\n';
    }
    return 0;
}

Несколько групп

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

#include <iostream>
#include <regex>

int main() {
    std::regex p("(\\d{4})-(\\d{2})-(\\d{2})");
    std::smatch m;
    std::string s = "2026-05-30";
    if (std::regex_match(s, m, p)) {
        std::cout << "Y=" << m[1] << " M=" << m[2] << " D=" << m[3] << '\n';
    }
    return 0;
}

str(), position(), length()

Каждая группа предоставляет str() для получения своего текста, position() для получения смещения и length() для получения размера внутри входных данных.

#include <iostream>
#include <regex>

int main() {
    std::regex p("(\\d+)");
    std::smatch m;
    std::string s = "abc 789 xyz";
    if (std::regex_search(s, m, p)) {
        std::cout << "str: " << m[1].str() << '\n';
        std::cout << "pos: " << m.position(1) << '\n';
        std::cout << "len: " << m.length(1) << '\n';
    }
    return 0;
}

Префикс и суффикс

Объект соответствия также предоставляет prefix() (текст перед соответствием) и suffix() (текст после него).

#include <iostream>
#include <regex>

int main() {
    std::regex p("\\d+");
    std::smatch m;
    std::string s = "left 55 right";
    if (std::regex_search(s, m, p)) {
        std::cout << "prefix: [" << m.prefix() << "]\n";
        std::cout << "suffix: [" << m.suffix() << "]\n";
    }
    return 0;
}

Группы без захвата

Используйте (?:...), чтобы объединить элементы без захвата. Это сохраняет смысл нумерованных групп, когда группировка нужна только для квантификаторов или чередования.

#include <iostream>
#include <regex>

int main() {
    std::regex p("(?:Mr|Ms) (\\w+)");
    std::smatch m;
    std::string s = "Ms Smith";
    if (std::regex_search(s, m, p)) {
        std::cout << "Name: " << m[1] << '\n';
    }
    return 0;
}

Проверка соответствия группы

Необязательная группа может не участвовать в сопоставлении. Проверьте значение matched у подсовпадения, чтобы узнать, захватила ли группа что-либо.

#include <iostream>
#include <regex>

int main() {
    std::regex p("file(\\.txt)?");
    std::smatch m;
    std::string s = "file";
    if (std::regex_match(s, m, p)) {
        std::cout << std::boolalpha << "ext matched: " << m[1].matched << '\n';
    }
    return 0;
}

Перебор всех соответствий

std::sregex_iterator проходит по каждому соответствию в строке и по пути предоставляет каждую группу.

#include <iostream>
#include <regex>

int main() {
    std::regex p("(\\d+)");
    std::string s = "a1 b22 c333";
    auto begin = std::sregex_iterator(s.begin(), s.end(), p);
    auto end = std::sregex_iterator();
    for (auto it = begin; it != end; ++it) {
        std::cout << (*it)[1] << '\n';
    }
    return 0;
}

Подсчёт соответствий

Объедините итератор с std::distance, чтобы подсчитать количество вхождений шаблона.

#include <iostream>
#include <regex>

int main() {
    std::regex p("\\d+");
    std::string s = "1 22 333 4444";
    auto begin = std::sregex_iterator(s.begin(), s.end(), p);
    auto end = std::sregex_iterator();
    std::cout << "Count: " << std::distance(begin, end) << '\n';
    return 0;
}

Извлечение пар ключ–значение

Две группы на одно соответствие позволяют разбирать простой структурированный текст, например токены key=value.

#include <iostream>
#include <regex>

int main() {
    std::regex p("(\\w+)=(\\w+)");
    std::string s = "a=1 b=2 c=3";
    auto begin = std::sregex_iterator(s.begin(), s.end(), p);
    auto end = std::sregex_iterator();
    for (auto it = begin; it != end; ++it) {
        std::cout << (*it)[1] << " -> " << (*it)[2] << '\n';
    }
    return 0;
}

Сохранение захваченных данных

Скопируйте захваченное подсовпадение в std::string с помощью str(), чтобы данные оставались действительными после уничтожения объекта соответствия.

#include <iostream>
#include <regex>
#include <string>

int main() {
    std::regex p("v(\\d+)");
    std::smatch m;
    std::string s = "version v7";
    std::string version;
    if (std::regex_search(s, m, p)) {
        version = m[1].str();
    }
    std::cout << "Stored: " << version << '\n';
    return 0;
}

Быстрая проверка

Проверьте своё понимание индексации групп захвата.

Итоги

Вы узнали, как извлекать данные с помощью групп захвата:

  • круглые скобки выполняют захват; (?:...) объединяет элементы без захвата
  • smatch[0] содержит всё соответствие, а [1] и последующие индексы — группы
  • str(), position(), length(), prefix(), suffix()
  • sregex_iterator проходит по каждому соответствию

Далее Вы узнаете, как преобразовывать текст с помощью поиска и замены.

Часто задаваемые вопросы

Урок «Группы захвата» бесплатный?

Да — полный текст урока «Группы захвата» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс C++ Academy, подпишись на CoddyKit PRO. Курс C++ Academy содержит 4 уроков всего.

Чему я научусь в уроке «Группы захвата»?

Извлекайте совпавшие части Ты практикуешь C++ Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать C++ Academy?

Предыдущий опыт не требуется. C++ Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.

Сколько времени занимает урок «Группы захвата»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке C++ Academy?

Да. Каждый урок C++ Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Основы regex
  2. Группы захвата
  3. Поиск и замена
  4. Замечания о производительности
← Назад к C++ Academy