Namespaces
Variants
Views
Actions

Difference between revisions of "cpp/regex/regex match"

From cppreference.com
< cpp‎ | regex
(Undo revision 31331 by 41.133.249.158 (talk))
m (Wording fix.)
 
(35 intermediate revisions by 15 users not shown)
Line 1: Line 1:
 
{{cpp/title|regex_match}}
 
{{cpp/title|regex_match}}
{{cpp/regex/sidebar}}
+
{{cpp/regex/navbar}}
{{ddcl list begin}}
+
{{dcl begin}}
{{ddcl list header | regex}}
+
{{dcl header|regex}}
{{ddcl list item | num=1 | notes={{mark since c++11}} | 1=
+
{{dcl|num=1|since=c++11|1=
template< class BidirectionalIterator,  
+
template< class BidirIt, class Alloc, class CharT, class Traits >
          class Alloc, class CharT, class Traits >
+
bool regex_match( BidirIt first, BidirIt last,
bool regex_match( BidirectionalIterator first, BidirectionalIterator last,
+
                   std::match_results<BidirIt, Alloc>& m,
                   std::match_results<BidirectionalIterator,Alloc>& m,
+
                   const std::basic_regex<CharT, Traits>& e,
                   const std::basic_regex<CharT,Traits>& e,
+
                   std::regex_constants::match_flag_type flags =
                   std::regex_constants::match_flag_type flags =  
+
 
                       std::regex_constants::match_default );
 
                       std::regex_constants::match_default );
 
}}
 
}}
{{ddcl list item | num=2 | notes={{mark since c++11}} | 1=
+
{{dcl|num=2|since=c++11|1=
template< class BidirectionalIterator,  
+
template< class BidirIt, class CharT, class Traits >
          class CharT, class Traits >
+
bool regex_match( BidirIt first, BidirIt last,
bool regex_match( BidirectionalIterator first, BidirectionalIterator last,
+
                   const std::basic_regex<CharT, Traits>& e,
                   const std::basic_regex<CharT,Traits>& e,
+
                   std::regex_constants::match_flag_type flags =
                   std::regex_constants::match_flag_type flags =  
+
 
                       std::regex_constants::match_default );
 
                       std::regex_constants::match_default );
 
}}
 
}}
{{ddcl list item | num=3 | notes={{mark since c++11}} | 1=
+
{{dcl|num=3|since=c++11|1=
 
template< class CharT, class Alloc, class Traits >
 
template< class CharT, class Alloc, class Traits >
 
bool regex_match( const CharT* str,
 
bool regex_match( const CharT* str,
                   std::match<const CharT*,Alloc>& m,
+
                   std::match_results<const CharT*, Alloc>& m,
                   const std::basic_regex<CharT,Traits>& e,
+
                   const std::basic_regex<CharT, Traits>& e,
                   std::regex_constants::match_flag_type flags =  
+
                   std::regex_constants::match_flag_type flags =
 
                       std::regex_constants::match_default );
 
                       std::regex_constants::match_default );
 
}}
 
}}
{{ddcl list item | num=4 | notes={{mark since c++11}} | 1=
+
{{dcl|num=4|since=c++11|1=
template< class STraits, class SAlloc,
+
          class Alloc, class CharT, class Traits >
+
bool regex_match( 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 );
+
}}
+
{{ddcl list item | num=5 | notes={{mark since c++11}} | 1=
+
 
template< class CharT, class Traits >
 
template< class CharT, class Traits >
bool regex_match( const CharT* str,
+
bool regex_match( const CharT* str, const std::basic_regex<CharT, Traits>& e,
                  const std::basic_regex<CharT,Traits>& e,
+
                   std::regex_constants::match_flag_type flags =
                   std::regex_constants::match_flag_type flags =  
+
 
                       std::regex_constants::match_default );
 
                       std::regex_constants::match_default );
 
}}
 
}}
{{ddcl list item | num=6 | notes={{mark since c++11}} | 1=
+
{{dcl|num=5|since=c++11|1=
template< class STraits, class SAlloc,  
+
template< class STraits, class SAlloc, class Alloc,
 
           class CharT, class Traits >
 
           class CharT, class Traits >
 +
bool regex_match
 +
    ( 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 );
 +
}}
 +
{{dcl|num=6|since=c++11|1=
 +
template< class STraits, class SAlloc, class CharT, class Traits >
 
bool regex_match( const std::basic_string<CharT, STraits, SAlloc>& s,
 
bool regex_match( const std::basic_string<CharT, STraits, SAlloc>& s,
                   const std::basic_regex<CharT,Traits>& e,
+
                   const std::basic_regex<CharT, Traits>& e,
                   std::regex_constants::match_flag_type flags =  
+
                   std::regex_constants::match_flag_type flags =
 
                       std::regex_constants::match_default );
 
                       std::regex_constants::match_default );
 
}}
 
}}
{{ddcl list end}}
+
{{dcl|num=7|since=c++11|1=
 +
template< class STraits, class SAlloc, class Alloc,
 +
          class CharT, class Traits >
 +
bool regex_match
 +
    ( 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;
 +
}}
 +
{{dcl end}}
  
1) Determines if there is a match between the regular express {{tt|e}} and the target character sequence {{tt|[first,last)}}.   Match results are returned in {{tt|m}}.
+
Determines if the regular expression {{c|e}} matches the entire target character sequence. The detailed match result is stored in {{c|m}} (if present).
  
2) Behaves as (1) above, omitting the match results.
+
@1,2@ The target character sequence is represented by the range {{range|first|last}}.
 +
{{rev begin}}
 +
{{rev|until=c++23|
 +
If {{tt|BidirIt}} does not satisfy the requirements of {{named req|BidirectionalIterator}}, the behavior is undefined.
 +
}}
 +
{{rev|since=c++23|
 +
If {{tt|BidirIt}} does not model {{lconcept|bidirectional_iterator}}, the behavior is undefined.
 +
}}
 +
{{rev end}}
  
3) Returns {{c|std::regex_match(str, str + std::char_traits<charT>::length(str), m, e, flags)}}.
+
@3,4@ The target character sequence is represented by the range {{range|str|str + std::char_traits<CharT>::length(str)}}.
  
4) Returns {{c|std::regex_match(s.begin(), s.end(), m, e, flags)}}.
+
@5,6@ The target character sequence is represented by the string {{c|s}}.
  
5) Returns {{c|std::regex_match(str, str + std::char_traits<charT>::length(str), e, flags)}}.
+
@7@ The target character sequence cannot be represented by a {{lc|std::string}} rvalue.
  
6) Returns {{c|std::regex_match(s.begin(), s.end(), e, flags)}}.
+
If the match does not exist, the following expressions involving {{c|m}} (if exists) should yield the specified values:
 +
{|class="wikitable" style="text-align: center;"
 +
!{{nbsp}}Expression{{nbsp}}
 +
!{{nbsp}}Value{{nbsp}}
 +
|-
 +
|{{box|{{c/core|m.}}{{ltt|cpp/regex/match_results/ready}}{{c/core|()}}}}
 +
|{{c|true}}
 +
|-
 +
|{{box|{{c/core|m.}}{{ltt|cpp/regex/match_results/size}}{{c/core|()}}}}
 +
|{{c|0}}
 +
|-
 +
|{{box|{{c/core|m.}}{{ltt|cpp/regex/match_results/empty}}{{c/core|()}}}}
 +
|{{c|true}}
 +
|}
 +
 
 +
If the match exists, given any integer in {{open range|​0|m.size()}} as {{c|n}}, the following expressions involving {{c|m}} should yield the specified values for each overload listed below:
 +
{|class="wikitable" style="text-align: center;"
 +
!rowspan=2|{{nbsp|6}}Expression{{nbsp|6}}
 +
!colspan=3|Value
 +
|-
 +
!{{nbsp|11}}Overload {{v|1}}{{nbsp|11}}
 +
!{{nbsp|11}}Overload {{v|3}}{{nbsp|11}}
 +
!{{nbsp|11}}Overload {{v|5}}{{nbsp|11}}
 +
|-
 +
|{{box|{{c/core|m.}}{{ltt|cpp/regex/match_results/ready}}{{c/core|()}}}}
 +
|colspan=3|{{c|true}}
 +
|-
 +
|{{box|{{c/core|m.}}{{ltt|cpp/regex/match_results/size}}{{c/core|()}}}}
 +
|colspan=3|{{box|{{c/core|1 + e.}}{{ltt|cpp/regex/basic_regex/mark_count}}{{c/core|()}}}}
 +
|-
 +
|{{box|{{c/core|m.}}{{ltt|cpp/regex/match_results/empty}}{{c/core|()}}}}
 +
|colspan=3|{{c|false}}
 +
|-
 +
|{{box|{{c/core|m.}}{{ltt|cpp/regex/match_results/prefix}}{{c/core|().first}}}}
 +
|rowspan=2|{{c|first}}
 +
|rowspan=2|{{c|str}}
 +
|rowspan=2|{{c|s.begin()}}
 +
|-
 +
|{{box|{{c/core|m.}}{{ltt|cpp/regex/match_results/prefix}}{{c/core|().second}}}}
 +
|-
 +
|{{box|{{c/core|m.}}{{ltt|cpp/regex/match_results/prefix}}{{c/core|().matched}}}}
 +
|colspan=3|{{nbsp|4}}{{c|false}}<ref>The match prefix is empty.</ref>
 +
|-
 +
|{{box|{{c/core|m.}}{{ltt|cpp/regex/match_results/suffix}}{{c/core|().first}}}}
 +
|rowspan=2|{{c|last}}
 +
|rowspan=2|<span style="text-align: start;">{{c multi|std::char_traits<CharT>::|    length(str) + str}}</span>
 +
|rowspan=2|{{c|s.end()}}
 +
|-
 +
|{{box|{{c/core|m.}}{{ltt|cpp/regex/match_results/suffix}}{{c/core|().second}}}}
 +
|-
 +
|{{box|{{c/core|m.}}{{ltt|cpp/regex/match_results/suffix}}{{c/core|().matched}}}}
 +
|colspan=3|{{nbsp|4}}{{c|false}}<ref>The match suffix is empty.</ref>
 +
|-
 +
|{{box|{{c/core|m}}{{ltt|cpp/regex/match_results/operator at|[0]}}{{c/core|.first}}}}
 +
|{{c|first}}
 +
|{{c|str}}
 +
|{{c|s.begin()}}
 +
|-
 +
|{{box|{{c/core|m}}{{ltt|cpp/regex/match_results/operator at|[0]}}{{c/core|.second}}}}
 +
|{{c|last}}
 +
|<span style="text-align: start;">{{c multi|std::char_traits<CharT>::|    length(str) + str}}</span>
 +
|{{c|s.end()}}
 +
|-
 +
|{{box|{{c/core|m}}{{ltt|cpp/regex/match_results/operator at|[0]}}{{c/core|.matched}}}}
 +
|colspan=3|{{nbsp|4}}{{c|true}}<ref>The entire sequence is matched.</ref>
 +
|-
 +
|{{box|{{c/core|m}}{{ltt|cpp/regex/match_results/operator at|[n]}}{{c/core|.first}}}}
 +
|colspan=3|
 +
* {{c|last}} if [[cpp/regex/ecmascript#Sub-expressions|marked sub-expression]] {{c|n}} did not participate in the match
 +
* the start of the sequence otherwise matching sub-expression {{c|n}} otherwise
 +
|-
 +
|{{box|{{c/core|m}}{{ltt|cpp/regex/match_results/operator at|[n]}}{{c/core|.second}}}}
 +
|colspan=3|
 +
* {{c|last}} if [[cpp/regex/ecmascript#Sub-expressions|marked sub-expression]] {{c|n}} did not participate in the match
 +
* the end of the sequence otherwise matching sub-expression {{c|n}} otherwise
 +
|-
 +
|{{box|{{c/core|m}}{{ltt|cpp/regex/match_results/operator at|[n]}}{{c/core|.matched}}}}
 +
|colspan=3|
 +
* {{c|false}} if [[cpp/regex/ecmascript#Sub-expressions|marked sub-expression]] {{c|n}} did not participate in the match
 +
* {{c|true}} otherwise
 +
|}
 +
<references/>
  
 
===Parameters===
 
===Parameters===
{{param list begin}}
+
{{par begin}}
{{param list item | first, last | the target character range to apply the regex to, given as iterators}}
+
{{par|first, last|the target character range}}
{{param list item | m | the match results}}
+
{{par|str|the target null-terminated C-style string}}
{{param list item | str | a target string, given as a null-terminated C-style string}}
+
{{par|s|the target {{lc|std::basic_string}}}}
{{param list item | s | a target string, given as a {{c|std::basic_string}} }}
+
{{par|m|the match results}}
{{param list item | e | the std::regex}}
+
{{par|e|the regular expression}}
{{param list item | flags | flags used to determine how the match will be performed}}
+
{{par|flags|flags used to determine how the match will be performed}}
{{param list end}}
+
{{par end}}
  
 
===Return value===
 
===Return value===
Returns {{c|true}} if a match exists, {{c|false}} otherwise.
+
Returns {{c|true}} if the entire target sequence matches {{c|e}}, {{c|false}} otherwise.
 +
 
 +
===Notes===
 +
Because {{tt|regex_match}} only considers full matches, the same regex may give different matches between {{tt|regex_match}} and {{lc|std::regex_search}}:
 +
{{source|1=
 +
std::regex re("Get{{!}}GetValue");
 +
std::cmatch m;
 +
std::regex_search("GetValue", m, re);  // returns true, and m[0] contains "Get"
 +
std::regex_match ("GetValue", m, re);  // returns true, and m[0] contains "GetValue"
 +
std::regex_search("GetValues", m, re); // returns true, and m[0] contains "Get"
 +
std::regex_match ("GetValues", m, re); // returns false
 +
}}
  
 
===Example===
 
===Example===
 
{{example
 
{{example
| code=
+
|code=
 +
#include <cstddef>
 
#include <iostream>
 
#include <iostream>
#include <string>
 
 
#include <regex>
 
#include <regex>
 +
#include <string>
  
 
int main()
 
int main()
 
{
 
{
     std::string fnames[] = {"foo.txt", "bar.txt", "zoidberg"};
+
     // Simple regular expression matching
 
+
    const std::string fnames[] = {"foo.txt", "bar.txt", "baz.dat", "zoidberg"};
     std::regex txt_regex("[a-z]+\\.txt");
+
     const std::regex txt_regex("[a-z]+\\.txt");
     for (const auto &fname : fnames) {
+
   
 +
     for (const auto& fname : fnames)
 
         std::cout << fname << ": " << std::regex_match(fname, txt_regex) << '\n';
 
         std::cout << fname << ": " << std::regex_match(fname, txt_regex) << '\n';
     }
+
      
 +
    // Extraction of a sub-match
 +
    const std::regex base_regex("([a-z]+)\\.txt");
 +
    std::smatch base_match;
 +
   
 +
    for (const auto& fname : fnames)
 +
        if (std::regex_match(fname, base_match, base_regex))
 +
            // The first sub_match is the whole string; the next
 +
            // sub_match is the first parenthesized expression.
 +
            if (base_match.size() == 2)
 +
            {
 +
                std::ssub_match base_sub_match = base_match[1];
 +
                std::string base = base_sub_match.str();
 +
                std::cout << fname << " has a base of " << base << '\n';
 +
            }
 +
   
 +
    // Extraction of several sub-matches
 +
    const std::regex pieces_regex("([a-z]+)\\.([a-z]+)");
 +
    std::smatch pieces_match;
 +
   
 +
    for (const auto& fname : fnames)
 +
        if (std::regex_match(fname, pieces_match, pieces_regex))
 +
        {
 +
            std::cout << fname << '\n';
 +
            for (std::size_t i = 0; i < pieces_match.size(); ++i)
 +
            {
 +
                std::ssub_match sub_match = pieces_match[i];
 +
                std::string piece = sub_match.str();
 +
                std::cout << "  submatch " << i << ": " << piece << '\n';
 +
            }
 +
        }
 
}
 
}
| output=
+
|output=
 
foo.txt: 1
 
foo.txt: 1
 
bar.txt: 1
 
bar.txt: 1
 +
baz.dat: 0
 
zoidberg: 0
 
zoidberg: 0
 +
foo.txt has a base of foo
 +
bar.txt has a base of bar
 +
foo.txt
 +
  submatch 0: foo.txt
 +
  submatch 1: foo
 +
  submatch 2: txt
 +
bar.txt
 +
  submatch 0: bar.txt
 +
  submatch 1: bar
 +
  submatch 2: txt
 +
baz.dat
 +
  submatch 0: baz.dat
 +
  submatch 1: baz
 +
  submatch 2: dat
 
}}
 
}}
 +
 +
===Defect reports===
 +
{{dr list begin}}
 +
{{dr list item|wg=lwg|dr=2205|std=C++11|before={{c|n}} could be zero in the postcondition|after=can only be positive}}
 +
{{dr list item|wg=lwg|dr=2273|std=C++11|before=it was unclear whether partial matches are considered|after=only considers full matches}}
 +
{{dr list item|wg=lwg|dr=2329|std=C++11|before=overload {{v|5}} accepted {{tt|basic_string}} rvalues,<br>which could result in dangling iterators|after=rejected via deleted overload {{v|7}}}}
 +
{{dr list end}}
  
 
===See also===
 
===See also===
{{dcl list begin}}
+
{{dsc begin}}
{{dcl list template | cpp/regex/dcl list basic_regex}}
+
{{dsc inc|cpp/regex/dsc basic_regex}}
{{dcl list template | cpp/regex/dcl list match_results}}
+
{{dsc inc|cpp/regex/dsc match_results}}
{{dcl list end}}
+
{{dsc inc|cpp/regex/dsc regex_search}}
 +
{{dsc end}}
 +
 
 +
{{langlinks|de|es|fr|it|ja|pt|ru|zh}}

Latest revision as of 18:55, 14 November 2024

Defined in header <regex>
template< class BidirIt, class Alloc, class CharT, class Traits >

bool regex_match( 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) (since C++11)
template< class BidirIt, class CharT, class Traits >

bool regex_match( BidirIt first, BidirIt last,
                  const std::basic_regex<CharT, Traits>& e,
                  std::regex_constants::match_flag_type flags =

                      std::regex_constants::match_default );
(2) (since C++11)
template< class CharT, class Alloc, class Traits >

bool regex_match( 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 );
(3) (since C++11)
template< class CharT, class Traits >

bool regex_match( const CharT* str, const std::basic_regex<CharT, Traits>& e,
                  std::regex_constants::match_flag_type flags =

                      std::regex_constants::match_default );
(4) (since C++11)
template< class STraits, class SAlloc, class Alloc,

          class CharT, class Traits >
bool regex_match
    ( 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 );
(5) (since C++11)
template< class STraits, class SAlloc, class CharT, class Traits >

bool regex_match( 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) (since C++11)
template< class STraits, class SAlloc, class Alloc,

          class CharT, class Traits >
bool regex_match
    ( 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) (since C++11)

Determines if the regular expression e matches the entire target character sequence. The detailed match result is stored in m (if present).

1,2) The target character sequence is represented by the range [firstlast).

If BidirIt does not satisfy the requirements of LegacyBidirectionalIterator, the behavior is undefined.

(until C++23)

If BidirIt does not model bidirectional_iterator, the behavior is undefined.

(since C++23)
3,4) The target character sequence is represented by the range [strstr + std::char_traits<CharT>::length(str)).
5,6) The target character sequence is represented by the string s.
7) The target character sequence cannot be represented by a std::string rvalue.

If the match does not exist, the following expressions involving m (if exists) should yield the specified values:

 Expression   Value 
m.ready() true
m.size() 0
m.empty() true

If the match exists, given any integer in (0m.size()) as n, the following expressions involving m should yield the specified values for each overload listed below:

      Expression       Value
           Overload (1)                       Overload (3)                       Overload (5)           
m.ready() true
m.size() 1 + e.mark_count()
m.empty() false
m.prefix().first first str s.begin()
m.prefix().second
m.prefix().matched     false[1]
m.suffix().first last std::char_traits<CharT>::
    length(str) + str
s.end()
m.suffix().second
m.suffix().matched     false[2]
m[0].first first str s.begin()
m[0].second last std::char_traits<CharT>::
    length(str) + str
s.end()
m[0].matched     true[3]
m[n].first
  • last if marked sub-expression n did not participate in the match
  • the start of the sequence otherwise matching sub-expression n otherwise
m[n].second
  • last if marked sub-expression n did not participate in the match
  • the end of the sequence otherwise matching sub-expression n otherwise
m[n].matched
  1. The match prefix is empty.
  2. The match suffix is empty.
  3. The entire sequence is matched.

Contents

[edit] Parameters

first, last - the target character range
str - the target null-terminated C-style string
s - the target std::basic_string
m - the match results
e - the regular expression
flags - flags used to determine how the match will be performed

[edit] Return value

Returns true if the entire target sequence matches e, false otherwise.

[edit] Notes

Because regex_match only considers full matches, the same regex may give different matches between regex_match and std::regex_search:

std::regex re("Get|GetValue");
std::cmatch m;
std::regex_search("GetValue", m, re);  // returns true, and m[0] contains "Get"
std::regex_match ("GetValue", m, re);  // returns true, and m[0] contains "GetValue"
std::regex_search("GetValues", m, re); // returns true, and m[0] contains "Get"
std::regex_match ("GetValues", m, re); // returns false

[edit] Example

#include <cstddef>
#include <iostream>
#include <regex>
#include <string>
 
int main()
{
    // Simple regular expression matching
    const std::string fnames[] = {"foo.txt", "bar.txt", "baz.dat", "zoidberg"};
    const std::regex txt_regex("[a-z]+\\.txt");
 
    for (const auto& fname : fnames)
        std::cout << fname << ": " << std::regex_match(fname, txt_regex) << '\n';
 
    // Extraction of a sub-match
    const std::regex base_regex("([a-z]+)\\.txt");
    std::smatch base_match;
 
    for (const auto& fname : fnames)
        if (std::regex_match(fname, base_match, base_regex))
            // The first sub_match is the whole string; the next
            // sub_match is the first parenthesized expression.
            if (base_match.size() == 2)
            {
                std::ssub_match base_sub_match = base_match[1];
                std::string base = base_sub_match.str();
                std::cout << fname << " has a base of " << base << '\n';
            }
 
    // Extraction of several sub-matches
    const std::regex pieces_regex("([a-z]+)\\.([a-z]+)");
    std::smatch pieces_match;
 
    for (const auto& fname : fnames)
        if (std::regex_match(fname, pieces_match, pieces_regex))
        {
            std::cout << fname << '\n';
            for (std::size_t i = 0; i < pieces_match.size(); ++i)
            {
                std::ssub_match sub_match = pieces_match[i];
                std::string piece = sub_match.str();
                std::cout << "  submatch " << i << ": " << piece << '\n';
            }
        }
}

Output:

foo.txt: 1
bar.txt: 1
baz.dat: 0
zoidberg: 0
foo.txt has a base of foo
bar.txt has a base of bar
foo.txt
  submatch 0: foo.txt
  submatch 1: foo
  submatch 2: txt
bar.txt
  submatch 0: bar.txt
  submatch 1: bar
  submatch 2: txt
baz.dat
  submatch 0: baz.dat
  submatch 1: baz
  submatch 2: dat

[edit] Defect reports

The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

DR Applied to Behavior as published Correct behavior
LWG 2205 C++11 n could be zero in the postcondition can only be positive
LWG 2273 C++11 it was unclear whether partial matches are considered only considers full matches
LWG 2329 C++11 overload (5) accepted basic_string rvalues,
which could result in dangling iterators
rejected via deleted overload (7)

[edit] See also

regular expression object
(class template) [edit]
identifies one regular expression match, including all sub-expression matches
(class template) [edit]
attempts to match a regular expression to any part of a character sequence
(function template) [edit]