Группы захвата
Извлекайте совпавшие части
«Группы захвата» — бесплатный урок 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 — локальная установка не требуется.
Все уроки этого курса
- Основы regex
- Группы захвата
- Поиск и замена
- Замечания о производительности