Regular Expressions in C++ with Examples: In Practice
\n\nRegular expressions (regex) are a powerful tool for text processing, allowing you to search, replace, and validate strings using complex patterns. In C++, support for regular expressions was introduced in the C++11 standard through the <regex> library. In this article, we will break down how to use std::regex in practice: from simple validations to data extraction and text replacement.
This material will be useful both for beginners just getting acquainted with C++ and for experienced developers looking to refresh their knowledge. We will cover the key functions: std::regex_match, std::regex_search, and std::regex_replace, as well as working with capture groups.
Core Components of the <regex> Library
\n\nBefore moving on to examples, let's understand the main classes and functions:
\n\n- \n
- std::regex — a class representing the regular expression itself (the pattern). It is created from a pattern string and an optional grammar flag (ECMAScript by default). \n
- std::smatch — a container for storing search results (for strings of type
std::string). An analog isstd::cmatchfor C-strings. \n - std::regex_match — checks if the entire string matches the pattern completely. \n
- std::regex_search — searches for a substring matching the pattern anywhere in the string. \n
- std::regex_replace — replaces all matches of the pattern with a specified string (with support for backreferences). \n
All functions accept flags to control behavior (e.g., std::regex_constants::icase for case-insensitive search).
Example 1: Validating a String Against a Pattern (std::regex_match)
\n\nThe simplest task is to check if a string matches a given format. For example, let's check if a string is a valid email address (simplified version):
\n\n#include <iostream>\n#include <regex>\n#include <string>\n\nint main() {\n std::string email = "user@example.com";\n // Pattern for email validation (simplified)\n std::regex pattern(R"([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,})");\n\n if (std::regex_match(email, pattern)) {\n std::cout << "Email is valid." << std::endl;\n } else {\n std::cout << "Email is invalid." << std::endl;\n }\n\n // Check an invalid email\n std::string bad_email = "user@.com";\n if (std::regex_match(bad_email, pattern)) {\n std::cout << "Email is valid." << std::endl;\n } else {\n std::cout << "Email is invalid." << std::endl;\n }\n\n return 0;\n}\n\nOutput:
\nEmail is valid.\nEmail is invalid.\n\nExplanation:
\n- \n
- We use a raw string literal
R"(...)"to avoid escaping backslashes. \n - The
std::regex_matchfunction returnstrueonly if the entire string completely matches the pattern. \n - The pattern
[a-zA-Z0-9._%+-]+means "one or more characters from the specified set". \n
Example 2: Searching for Substrings and Extracting Data (std::regex_search)
\n\nOften you need not just to validate, but to find all occurrences of a pattern and extract parts of the string. For this, std::regex_search is used in a loop. In the following example, we will find all phone numbers in the format +7-XXX-XXX-XX-XX in the text and extract the operator code:
#include <iostream>\n#include <regex>\n#include <string>\n\nint main() {\n std::string text = "Contacts: +7-495-123-45-67 and +7-916-987-65-43. Additional number: +7-495-111-22-33.";\n // Pattern: +7-code(3 digits)-... (capture groups for code and the rest)\n std::rege