C++—正则表达式

1. 匹配

基础用法:

#include 
#include 
#include 

int main()
{
    using namespace std::regex_constants;

    std::string filename("Foo.txt");
    std::regex pattern("[a-z]+\\.txt", ECMAScript|icase);    // icase: 忽略大小写

    // filename 是否匹配 pattern
    bool matched = std::regex_match(filename, pattern);
    std::cout << std::boolalpha << matched;            // true
}

提取子匹配(分组):

std::string filename("foo.txt");
std::regex pattern("([a-z]+)\\.([a-z]+)");
std::smatch groups;

// 如果 filename 匹配 pattern,则将匹配结果存入 groups 中
bool matched = std::regex_match(filename, groups, pattern);
if (matched)
{
    for (size_t i = 0; i < groups.size(); i++)
    {
        /*
        groups[0] 是整个匹配的内容;
        groups[1] 是第一匹配分组的内容,以此类推。
        */
        std::ssub_match group = groups[i];
        std::cout << "groups[" << i << "]: " << group.str() << '\n';
    }
}
groups[0]: foo.txt
groups[1]: foo
groups[2]: txt

2. 搜索

基础用法:

std::string s("Roses are #ff0000, violets are #0000ff.");
std::regex pattern("#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})");
std::smatch groups;
auto itBegin = s.cbegin(), itEnd = s.cend();

// 在 [itBegin, itEnd) 中搜索匹配 pattern 的内容,并将匹配结果存入 groups 中
while (std::regex_search(itBegin, itEnd, groups, pattern))
{
    for (size_t i = 0; i < groups.size(); i++)
    {
        /*
        groups[0] 是整个匹配的内容;
        groups[1] 是第一匹配分组的内容,以此类推。
        */
        std::ssub_match group = groups[i];
        std::cout << "groups[" << i << "]: " << group.str() << '\n';
    }
    std::cout << "---------------\n";

    // 第 0 个匹配分组的范围:[groups[0].first, groups[0].second)
    itBegin = groups[0].second;
}
groups[0]: #ff0000
groups[1]: ff
groups[2]: 00
groups[3]: 00
---------------
groups[0]: #0000ff
groups[1]: 00
groups[2]: 00
groups[3]: ff
---------------

使用正则迭代器来遍历所有匹配的内容:

std::string s("Roses are #ff0000, violets are #0000ff.");
std::regex pattern("#[a-f0-9]{6}");

auto itBegin = std::sregex_iterator(s.begin(), s.end(), pattern);
auto itEnd = std::sregex_iterator();

for (auto it = itBegin; it != itEnd; it++)
{
    // 指向 std::smatch 类型
    std::cout << it->str() << '\n';
}
#ff0000
#0000ff

3. 替换

std::string s("phone number and qq number: 123456789,  987654321.");
std::regex pattern("([0-9]+),\\s+([0-9]+)");

// 将 s 中匹配 pattern 的内容替换成 [$&]
// $&: 引用整个匹配的内容
std::string result = std::regex_replace(s, pattern, "[$&]");
std::cout << result << '\n';

// $1: 引用第一个匹配分组的内容,以此类推
result = std::regex_replace(s, pattern, "$2, $1");
std::cout << result << '\n';
phone number and qq number: [123456789,  987654321].
phone number and qq number: 987654321, 123456789.

4. smatch

using smatch  = match_results;
std::smatch groups;

std::size_t n = groups.size();      // 有多少个匹配分组(包括整个匹配)
int len = groups.length(1);         // 第一个匹配分组的长度
int pos = groups.position(1);       // 第一个匹配分组的起始位置
std::string s = groups.str(1);      // 第一个匹配分组的字符串表示
std::ssub_match group = groups[1];  // 第一个匹配分组
std::ssub_match prefix = groups.prefix();   // 匹配内容之前的内容
std::ssub_match suffix = groups.suffix();   // 匹配内容之后的内容

// 迭代器
for (auto it = groups.cbegin(); it != groups.cend(); it++)
{
    std::ssub_match group = *it;
}

5. ssub_match

using ssub_match  = sub_match;
std::ssub_match group;

auto itBegin = group.first;     // 匹配分组的起始位置(迭代器)
auto itEnd = group.second;      // 匹配分组的尾后位置(迭代器)
auto len = group.length();      // 匹配分组的长度
std::string s = group.str();    // 匹配分组的字符串表示

你可能感兴趣的