Skip to content

Regex

Regex

The regular expressions library provides a class that represents regular expressions, which are a kind of mini-language used to perform pattern matching within strings.

1
#include <regex>

1
2
3
if (std::regex_match("subject", std::regex("(sub)(.*)"))) {
    std::cout << "subject matches expression (sub)(.*)" << '\n';
}

1
2
3
4
5
6
const char cstr[] = "subject";
std::string s("subject");
std::regex e("(sub)(.*)");
if (regex_match(s, e)) {
    std::cout << "subject matches expression (sub)(.*)" << '\n';
}

1
2
3
if (std::regex_match(s.begin(), s.end(), e)) {
    std::cout << "subject matches expression (sub)(.*)" << '\n';
}

1
2
std::cmatch cm; // same as `match_results<const char*>`
std::regex_match(cstr, cm, e);

1
2
3
4
5
6
std::cout << "literal string with " << cm.size() << " matches" << '\n';
std::cout << "The literal string matches were: ";
for (const auto &i : cm) {
    std::cout << "[" << i << "] ";
}
std::cout << '\n';

1
2
std::smatch sm; // match_results<string::const_iterator>
std::regex_match(s, sm, e);

1
2
3
4
5
6
std::cout << "string object with " << sm.size() << " matches" << '\n';
std::cout << "The string matches were: ";
for (const auto &i : sm) {
    std::cout << "[" << i << "] ";
}
std::cout << '\n';

1
2
std::smatch sm; // match_results<string::const_iterator>
std::regex_match(s, sm, e);

1
std::regex_match(cstr, cm, e, std::regex_constants::match_default);

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
std::string ss = "foo bar 123";
std::regex r("([a-zA-Z]+)|(d+)");
std::sregex_iterator match_it(ss.begin(), ss.end(), r);
for (; match_it != std::sregex_iterator(); ++match_it) {
    std::smatch m = *match_it;
    // Match
    std::cout << "Match value: " << m.str() << " at position "
              << m.position() << '\n';
    // Groups
    for (size_t index = 1; index < m.size(); ++index) {
        if (!m[index].str().empty()) {
            std::cout << "Capture group ID: " << index - 1 << '\n';
            break;
        }
    }
}

1
2
3
4
5
6
7
std::string var = "first second third forth";
if (regex_match(var, sm, std::regex("(.*) (.*) (.*) (.*)"))) {
    for (size_t i = 1; i < sm.size(); i++) {
        std::cout << "Match " << i << ": " << sm[i] << " at position "
                  << sm.position(i) << '\n';
    }
}

1
2
3
4
5
6
7
auto implode = [](const std::vector<std::string> &strs,
                  const std::string &delim) {
    std::stringstream s;
    copy(strs.begin(), strs.end(),
         std::ostream_iterator<std::string>(s, delim.c_str()));
    return s.str();
};

1
2
3
4
5
var = "user/32";
std::smatch sm2;
std::vector<std::string> routes = {"welcome", "user/\\d+", "post/[a-zA-Z]+",
                                   "about"};
std::regex disjunction("(" + implode(routes, ")|(") + ")");

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
if (std::regex_match(var, sm2, disjunction,
                     std::regex_constants::match_not_null)) {
    for (size_t index = 1; index < sm2.size(); ++index) {
        if (sm2[index].length() > 0) {
            std::cout << "Capture group index: " << index - 1 << '\n';
            std::cout << var << " matched route " << routes[index - 1]
                      << '\n';
            break;
        }
    }
}

Share Snippets