# std::regex_search

< cpp‎ | regex

定义于头文件 `<regex>` |  |
template< class BidirIt, class Alloc, class CharT, class Traits > bool regex_search( BidirIt first, BidirIt last, std::match_results<BidirIt,Alloc>& m, const std::basic_regex<CharT,Traits>& e, std::regex_constants::match_flag_type flags = std::regex_constants::match_default ); | (1) | (C++11 起)
template< class CharT, class Alloc, class Traits > bool regex_search( const CharT* str, std::match_results<const CharT*,Alloc>& m, const std::basic_regex<CharT,Traits>& e, std::regex_constants::match_flag_type flags = std::regex_constants::match_default ); | (2) | (C++11 起)
template< class STraits, class SAlloc, class Alloc, class CharT, class Traits > bool regex_search( const std::basic_string<CharT,STraits,SAlloc>& s, std::match_results< typename std::basic_string<CharT,STraits,SAlloc>::const_iterator, Alloc >& m, const std::basic_regex<CharT, Traits>& e, std::regex_constants::match_flag_type flags = std::regex_constants::match_default ); | (3) | (C++11 起)
template< class BidirIt, class CharT, class Traits > bool regex_search( BidirIt first, BidirIt last, const std::basic_regex<CharT,Traits>& e, std::regex_constants::match_flag_type flags = std::regex_constants::match_default ); | (4) | (C++11 起)
template< class CharT, class Traits > bool regex_search( const CharT* str, const std::basic_regex<CharT,Traits>& e, std::regex_constants::match_flag_type flags = std::regex_constants::match_default ); | (5) | (C++11 起)
template< class STraits, class SAlloc, class CharT, class Traits > bool regex_search( const std::basic_string<CharT,STraits,SAlloc>& s, const std::basic_regex<CharT,Traits>& e, std::regex_constants::match_flag_type flags = std::regex_constants::match_default ); | (6) | (C++11 起)
template< class STraits, class SAlloc, class Alloc, class CharT, class Traits > bool regex_search( const std::basic_string<CharT,STraits,SAlloc>&&, std::match_results< typename std::basic_string<CharT,STraits,SAlloc>::const_iterator, Alloc >&, const std::basic_regex<CharT, Traits>&, std::regex_constants::match_flag_type flags = std::regex_constants::match_default ) = delete; | (7) | (C++11 起)

确定正则表达式 `e` 和目标字符序列中的某个子序列间是否有匹配。

1) 分析泛型范围 `[first,last)` 。返回匹配结果于 `m` 。
2) 分析 `str` 所指向的空终止字符串。返回匹配结果于 `m` 。
3) 分析 string `s` 。返回匹配结果于 `m` 。
4-6) 等价于 (1-3) ，只是省略匹配结果。
7) 禁止重载 (3) 接受临时字符串，否则此函数将以立即变为非法的 string 迭代器填充 `match_results` `m` 。

`regex_search` 将成功地匹配给定序列的任何子序列，相对地 std::regex_match 仅若正则表达式匹配整个序列才返回 true 。

### 参数

first, last | - | 标识目标字符序列的范围
str | - | 指向空终止字符序列的指针
s | - | 标识目标字符序列的指针
e | - | 应当应用到目标字符序列的 std::regex
m | - | 匹配结果
flags | - | 掌管搜索行为的 std::regex_constants::match_flag_type
类型要求
- `BidirIt` 必须满足老式双向迭代器 (LegacyBidirectionalIterator) 的要求。
- `Alloc` 必须满足分配器 (Allocator) 的要求。

### 返回值

若匹配存在则返回 true ，否则返回 false 。任一情况下，更新对象 `m` 如下：

若匹配不存在：

m.ready() == true
m.empty() == true
m.size() == 0

若匹配存在：

m.ready() | true
m.empty() | false
m.size() | 有标记子表达式的数量加 1 ，即 1+e.mark_count()
m.prefix().first | `first`
m.prefix().second | m[0].first
m.prefix().matched | m.prefix().first != m.prefix().second
m.suffix().first | m[0].second
m.suffix().second | `last`
m.suffix().matched | m.suffix().first != m.suffix().second
m[0].first | 匹配序列的起始
m[0].second | 匹配数列的结尾
m[0].matched | true
m[n].first | 匹配有标记子表达式 n 的序列的起始，或若子表达式不参与匹配则为 `last`
m[n].second | 匹配有标记子表达式 n 的序列的结尾，或若子表达式不参与匹配则为 `last`
m[n].matched | 若子表达式 n 参与匹配则为 true ，否则为 false

### 注解

为在目标序列内检验所有匹配，可在循环中调用 `std::regex_search` ，每次从先前调用的 `m[0].second` 重新开始。 std::regex_iterator 提供对此迭代的简易接口。

### 示例

    #include <iostream>
    #include <string>
    #include <regex>

    int main()
    {
        std::string lines[] = {"Roses are #ff0000",
                               "violets are #0000ff",
                               "all of my base are belong to you"};

        std::regex color_regex("#([a-f0-9]{2})"
                                "([a-f0-9]{2})"
                                "([a-f0-9]{2})");

        // 简单匹配
        for (const auto &line : lines) {
            std::cout << line << ": " << std::boolalpha
                      << std::regex_search(line, color_regex) << '\n';
        }
        std::cout << '\n';

        // 展示每个匹配中有标记子表达式的内容
        std::smatch color_match;
        for (const auto& line : lines) {
            if(std::regex_search(line, color_match, color_regex)) {
                std::cout << "matches for '" << line << "'\n";
                std::cout << "Prefix: '" << color_match.prefix() << "'\n";
                for (size_t i = 0; i < color_match.size(); ++i)
                    std::cout << i << ": " << color_match[i] << '\n';
                std::cout << "Suffix: '" << color_match.suffix() << "\'\n\n";
            }
        }

        // 重复搜索（参阅 std::regex_iterator ）
        std::string log(R"(
            Speed:  366
            Mass:   35
            Speed:  378
            Mass:   32
            Speed:  400
            Mass:   30)");
        std::regex r(R"(Speed:\t\d*)");
        std::smatch sm;
        while(regex_search(log, sm, r))
        {
            std::cout << sm.str() << '\n';
            log = sm.suffix();
        }

        // C 风格字符串演示
        std::cmatch cm;
        if(std::regex_search("this is a test", cm, std::regex("test")))
            std::cout << "\nFound " << cm[0] << " at position " << cm.prefix().length();
    }

输出：

    Roses are #ff0000: true
    violets are #0000ff: true
    all of my base are belong to you: false

    matches for 'Roses are #ff0000'
    Prefix: 'Roses are '
    0: #ff0000
    1: ff
    2: 00
    3: 00
    Suffix: ''

    matches for 'violets are #0000ff'
    Prefix: 'violets are '
    0: #0000ff
    1: 00
    2: 00
    3: ff
    Suffix: ''

    Speed:  366
    Speed:  378
    Speed:  400

    Found test at position 10

### 缺陷报告

下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。

DR | 应用于 | 出版时的行为 | 正确行为
--- | --- | --- | ---
LWG 2329 | C++11 | 曾接受 `basic_string` 右值，这较可能导致悬垂迭代器 | 通过被删除的重载拒绝

### 参阅

basic_regex (C++11) | 正则表达式对象 (类模板)
match_results (C++11) | 标识一个正则表达式匹配，包含所有子表达式匹配 (类模板)
regex_match (C++11) | 尝试匹配一个正则表达式到整个字符序列 (函数模板)