【2024|第15代版本Linux C/C++全栈开发合集(职场常用/面试常问技术点+项目实战)】

C++11引入了正则表达式支持,使得C++标准库可以处理字符串模式匹配和搜索。C++标准库中的正则表达式功能集中在<regex>头文件中,主要包含以下几个核心类和函数:

核心类和函数

  1. std::regex:表示一个正则表达式对象,用于模式匹配。
  2. std::smatchstd::cmatch:分别用于存储字符串(std::string)和C风格字符串(const char*)的匹配结果。
  3. std::regex_search:在输入序列中搜索正则表达式的匹配。
  4. std::regex_match:检测整个输入序列是否匹配正则表达式。
  5. std::regex_replace:使用正则表达式替换输入序列中的子字符串。

常用方法和用法

1. std::regex

正则表达式的定义和使用:

#include <iostream>
#include <regex>

int main() {
    std::string pattern = R"(\d+)";
    std::regex re(pattern);
    return 0;
}

R"(\d+)" 是一个原始字符串文字,避免了反斜杠转义的问题。

2. std::regex_match

用于检查整个字符串是否匹配给定的正则表达式:

#include <iostream>
#include <regex>

int main() {
    std::string s = "12345";
    std::regex re(R"(\d+)");
    
    if (std::regex_match(s, re)) {
        std::cout << "The entire string is a number.\n";
    } else {
        std::cout << "The string is not a number.\n";
    }

    return 0;
}
3. std::regex_search

用于在字符串中搜索正则表达式的匹配:

#include <iostream>
#include <regex>

int main() {
    std::string s = "Hello 123 World";
    std::regex re(R"(\d+)");
    std::smatch match;

    if (std::regex_search(s, match, re)) {
        std::cout << "Found a number: " << match.str() << '\n';
    } else {
        std::cout << "No number found.\n";
    }

    return 0;
}
4. std::regex_replace

用于替换字符串中所有匹配正则表达式的部分:

#include <iostream>
#include <regex>

int main() {
    std::string s = "Hello 123 World 456";
    std::regex re(R"(\d+)");
    std::string result = std::regex_replace(s, re, "NUMBER");

    std::cout << result << '\n';  // 输出: Hello NUMBER World NUMBER

    return 0;
}
5.std::regex_iteratorstd::sregex_iterator

std::regex_iteratorstd::sregex_iterator 是 C++11 中用于正则表达式匹配结果的迭代器,提供了一种便利的方式来遍历字符串中所有与正则表达式匹配的子字符串。

std::regex_iterator

std::regex_iterator 是一个模板类,用于遍历使用正则表达式匹配结果的迭代器。它可以用于所有字符类型的字符串(如 charwchar_t 等)。常用的实例是 std::sregex_iterator,它专门用于 std::string 类型的字符串。

std::sregex_iterator

std::sregex_iteratorstd::regex_iterator 的特化,用于处理 std::string 类型的字符串。它遍历 std::string 中与 std::regex 匹配的所有子字符串。

构造函数
  • std::sregex_iterator():默认构造函数,创建一个指向末尾的迭代器。
  • std::sregex_iterator(std::string::const_iterator begin, std::string::const_iterator end, const std::regex& re, std::regex_constants::match_flag_type flags = std::regex_constants::match_default):创建一个迭代器,遍历 [begin, end) 范围内所有与正则表达式 re 匹配的子字符串。
主要成员函数
  • operator*:解引用运算符,返回当前匹配结果。
  • operator++:前缀和后缀递增运算符,用于移动到下一个匹配结果。
  • operator==operator!=:比较运算符,用于判断迭代器是否相等。
5.std::regex_constants::match_flag_type

std::regex_constants::match_flag_type 是 C++11 标准库中定义的一组标志,用于控制正则表达式匹配的行为。它们可以作为参数传递给正则表达式匹配函数。

常用的 std::regex_constants::match_flag_type 标志

以下是常用的匹配标志及其详细说明:

  • std::regex_constants::match_default:默认的匹配行为,等同于没有指定其他标志时的行为。
  • std::regex_constants::match_not_bol:不匹配输入序列的开始位置 ^
  • std::regex_constants::match_not_eol:不匹配输入序列的结束位置 $
  • std::regex_constants::match_not_bow:不匹配单词的开始位置 \b
  • std::regex_constants::match_not_eow:不匹配单词的结束位置 \b
  • std::regex_constants::match_any:允许任何匹配。
  • std::regex_constants::match_not_null:禁止空匹配。
  • std::regex_constants::match_continuous:要求从目标序列的第一个字符开始匹配。
  • std::regex_constants::match_prev_avail:目标序列的迭代器的前一个位置有效,可以用于 ^ 匹配。
  • std::regex_constants::format_default:默认的格式替换行为。
  • std::regex_constants::format_sed:使用 sed 风格的替换行为。
  • std::regex_constants::format_no_copy:只替换匹配的部分,不复制不匹配的部分。
  • std::regex_constants::format_first_only:只替换第一个匹配项。
示例与解释

下面是一些示例,展示了如何使用这些匹配标志来控制正则表达式的行为:

示例1:基本匹配

#include <iostream>
#include <regex>

int main() {
    std::string text = "Hello, World!";
    std::regex re(R"(Hello)");

    if (std::regex_search(text, re, std::regex_constants::match_default)) {
        std::cout << "Found 'Hello' at the beginning of the string.\n";
    }

    return 0;
}

示例2:不匹配输入序列的开始位置

#include <iostream>
#include <regex>

int main() {
    std::string text = "Hello, World!";
    std::regex re(R"(^World)");

    if (!std::regex_search(text, re, std::regex_constants::match_not_bol)) {
        std::cout << "'World' was not found at the beginning of the string.\n";
    } else {
        std::cout << "'World' was found.\n";
    }

    return 0;
}

示例3:不匹配输入序列的结束位置

#include <iostream>
#include <regex>

int main() {
    std::string text = "Hello, World!";
    std::regex re(R"(World!$)");

    if (!std::regex_search(text, re, std::regex_constants::match_not_eol)) {
        std::cout << "'World!' was not found at the end of the string.\n";
    } else {
        std::cout << "'World!' was found.\n";
    }

    return 0;
}

示例4:禁止空匹配

#include <iostream>
#include <regex>

int main() {
    std::string text = "a1b2c3";
    std::regex re(R"(\d*)");

    auto words_begin = std::sregex_iterator(text.begin(), text.end(), re, std::regex_constants::match_not_null);
    auto words_end = std::sregex_iterator();

    for (std::sregex_iterator i = words_begin; i != words_end; ++i) {
        std::smatch match = *i;
        std::cout << "Match: " << match.str() << '\n';
    }

    return 0;
}

示例5:只替换第一个匹配项

#include <iostream>
#include <regex>

int main() {
    std::string text = "one fish, two fish, red fish, blue fish";
    std::regex re(R"(fish)");
    std::string result = std::regex_replace(text, re, "shark", std::regex_constants::format_first_only);

    std::cout << result << '\n';  // 输出: one shark, two fish, red fish, blue fish

    return 0;
}
组合标志

可以组合多个标志来实现更复杂的匹配行为。例如,使用 std::regex_constants::match_not_bol | std::regex_constants::match_not_eol 可以在同一个匹配操作中同时禁用行首和行尾匹配。

#include <iostream>
#include <regex>

int main() {
    std::string text = "Hello, World!";
    std::regex re(R"(^Hello|World!$)");

    if (std::regex_search(text, re, std::regex_constants::match_not_bol | std::regex_constants::match_not_eol)) {
        std::cout << "Found 'Hello' not at the beginning or 'World!' not at the end of the string.\n";
    } else {
        std::cout << "'Hello' was found at the beginning or 'World!' was found at the end.\n";
    }

    return 0;
}

通过理解并使用 std::regex_constants::match_flag_type 中的各种标志,可以更灵活地控制正则表达式的匹配行为,以满足不同的需求。

正则表达式的构建

常用的正则表达式构建元素:

  • . 匹配除换行符外的任何字符
  • ^ 匹配字符串的开始
  • $ 匹配字符串的结束
  • * 匹配前面的子表达式零次或多次
  • + 匹配前面的子表达式一次或多次
  • ? 匹配前面的子表达式零次或一次
  • \d 匹配一个数字字符
  • \w 匹配一个字母、数字或下划线字符
  • [abc] 匹配方括号中的任何字符
  • (a|b) 匹配ab
  • {n} 匹配前面的子表达式恰好n次
  • {n,} 匹配前面的子表达式至少n次
  • {n,m} 匹配前面的子表达式至少n次但不超过m次