1[/ 2 Copyright 2006-2007 John Maddock. 3 Distributed under the Boost Software License, Version 1.0. 4 (See accompanying file LICENSE_1_0.txt or copy at 5 http://www.boost.org/LICENSE_1_0.txt). 6] 7 8 9[section:regex_iterator regex_iterator] 10 11The iterator type [regex_iterator] will enumerate all of the regular expression 12matches found in some sequence: dereferencing a [regex_iterator] yields a 13reference to a [match_results] object. 14 15 template <class BidirectionalIterator, 16 class charT = iterator_traits<BidirectionalIterator>::value_type, 17 class traits = regex_traits<charT> > 18 class regex_iterator 19 { 20 public: 21 typedef basic_regex<charT, traits> regex_type; 22 typedef match_results<BidirectionalIterator> value_type; 23 typedef typename iterator_traits<BidirectionalIterator>::difference_type difference_type; 24 typedef const value_type* pointer; 25 typedef const value_type& reference; 26 typedef std::forward_iterator_tag iterator_category; 27 28 ``[link boost_regex.regex_iterator.construct1 regex_iterator]``(); 29 ``[link boost_regex.regex_iterator.construct2 regex_iterator]``(BidirectionalIterator a, BidirectionalIterator b, 30 const regex_type& re, 31 match_flag_type m = match_default); 32 ``[link boost_regex.regex_iterator.construct3 regex_iterator]``(const regex_iterator&); 33 regex_iterator& ``[link boost_regex.regex_iterator.assign operator=(]``const regex_iterator&); 34 bool ``[link boost_regex.regex_iterator.op_eq operator==]``(const regex_iterator&)const; 35 bool ``[link boost_regex.regex_iterator.op_ne operator!=]``(const regex_iterator&)const; 36 const value_type& ``[link boost_regex.regex_iterator.op_deref operator*]``()const; 37 const value_type* ``[link boost_regex.regex_iterator.op_arrow operator->]``()const; 38 regex_iterator& ``[link boost_regex.regex_iterator.op_inc operator++]``(); 39 regex_iterator ``[link boost_regex.regex_iterator.op_inc2 operator++]``(int); 40 }; 41 42 typedef regex_iterator<const char*> cregex_iterator; 43 typedef regex_iterator<std::string::const_iterator> sregex_iterator; 44 45 #ifndef BOOST_NO_WREGEX 46 typedef regex_iterator<const wchar_t*> wcregex_iterator; 47 typedef regex_iterator<std::wstring::const_iterator> wsregex_iterator; 48 #endif 49 50 template <class charT, class traits> regex_iterator<const charT*, charT, traits> 51 ``[link boost_regex.regex_iterator.make make_regex_iterator]``(const charT* p, const basic_regex<charT, traits>& e, 52 regex_constants::match_flag_type m = regex_constants::match_default); 53 54 template <class charT, class traits, class ST, class SA> 55 regex_iterator<typename std::basic_string<charT, ST, SA>::const_iterator, charT, traits> 56 ``[link boost_regex.regex_iterator.make make_regex_iterator]``(const std::basic_string<charT, ST, SA>& p, 57 const basic_regex<charT, traits>& e, 58 regex_constants::match_flag_type m = regex_constants::match_default); 59 60 61[h4 Description] 62 63A [regex_iterator] is constructed from a pair of iterators, and enumerates 64all occurrences of a regular expression within that iterator range. 65 66[#boost_regex.regex_iterator.construct1] 67 68 regex_iterator(); 69 70[*Effects]: constructs an end of sequence [regex_iterator]. 71 72[#boost_regex.regex_iterator.construct2] 73 74 regex_iterator(BidirectionalIterator a, BidirectionalIterator b, 75 const regex_type& re, 76 match_flag_type m = match_default); 77 78[*Effects]: constructs a [regex_iterator] that will enumerate all occurrences of 79the expression /re/, within the sequence \[a,b), and found using [match_flag_type] /m/. 80The object /re/ must exist for the lifetime of the [regex_iterator]. 81 82[*Throws]: `std::runtime_error` if the complexity of matching the expression 83against an N character string begins to exceed O(N[super 2]), or if the program 84runs out of stack space while matching the expression (if Boost.Regex is 85configured in recursive mode), or if the matcher exhausts its permitted 86memory allocation (if Boost.Regex is configured in non-recursive mode). 87 88[#boost_regex.regex_iterator.construct3] 89 90 regex_iterator(const regex_iterator& that); 91 92[*Effects]: constructs a copy of `that`. 93 94[*Postconditions]: `*this == that`. 95 96 97[#boost_regex.regex_iterator.assign] 98 99 regex_iterator& operator=(const regex_iterator&); 100 101[*Effects]: sets `*this` equal to those in `that`. 102 103[*Postconditions]: *this == that. 104 105 106[#boost_regex.regex_iterator.op_eq] 107 108 bool operator==(const regex_iterator& that)const; 109 110[*Effects]: returns true if *this is equal to that. 111 112 113[#boost_regex.regex_iterator.op_ne] 114 115 bool operator!=(const regex_iterator&)const; 116 117[*Effects]: returns `!(*this == that)`. 118 119 120[#boost_regex.regex_iterator.op_deref] 121 122 const value_type& operator*()const; 123 124[*Effects]: dereferencing a [regex_iterator] object it yields a const reference 125to a [match_results] object, whose members are set as follows: 126 127[table 128[[Element][Value]] 129[[`(*it).size()`][`1 + re.mark_count()`]] 130[[`(*it).empty()`][`false`]] 131[[`(*it).prefix().first`][The end of the last match found, or the start 132 of the underlying sequence if this is the first match enumerated]] 133[[`(*it).prefix().last`][The same as the start of the match found: 134 `(*it)[0].first`]] 135[[`(*it).prefix().matched`][True if the prefix did not match an empty string: 136 `(*it).prefix().first != (*it).prefix().second`]] 137[[`(*it).suffix().first`][The same as the end of the match found: 138 `(*it)[0].second`]] 139[[`(*it).suffix().last`][The end of the underlying sequence.]] 140[[`(*it).suffix().matched`][True if the suffix did not match an empty string: 141 `(*it).suffix().first != (*it).suffix().second`]] 142[[`(*it)[0].first`][The start of the sequence of characters that matched the regular expression]] 143[[`(*it)[0].second`][The end of the sequence of characters that matched the regular expression]] 144[[`(*it)[0].matched`][true if a full match was found, and false if it was a partial match (found as a result of the match_partial flag being set).]] 145[[`(*it)[n].first`][For all integers `n < (*it).size()`, the start of the sequence 146 that matched sub-expression /n/. Alternatively, if sub-expression /n/ 147 did not participate in the match, then last.]] 148[[`(*it)[n].second`][For all integers `n < (*it).size()`, the end of the sequence 149 that matched sub-expression /n/. Alternatively, if sub-expression /n/ did 150 not participate in the match, then last.]] 151[[`(*it)[n].matched`][For all integers `n < (*it).size()`, true if sub-expression /n/ 152 participated in the match, false otherwise.]] 153[[`(*it).position(n)`][For all integers `n < (*it).size()`, then the distance from 154 the start of the underlying sequence to the start of sub-expression match /n/.]] 155] 156 157 158[#boost_regex.regex_iterator.op_arrow] 159 160 const value_type* operator->()const; 161 162[*Effects]: returns `&(*this)`. 163 164 165[#boost_regex.regex_iterator.op_inc] 166 167 regex_iterator& operator++(); 168 169[*Effects]: moves the iterator to the next match in the underlying sequence, or 170the end of sequence iterator if none if found. When the last match found 171matched a zero length string, then the [regex_iterator] will find the next match as 172follows: if there exists a non-zero length match that starts at the same 173location as the last one, then returns it, otherwise starts looking for the 174next (possibly zero length) match from one position to the right of the last match. 175 176[*Throws]: `std::runtime_error` if the complexity of matching the expression 177against an N character string begins to exceed O(N[super 2]), or if the 178program runs out of stack space while matching the expression (if Boost.Regex is 179configured in recursive mode), or if the matcher exhausts its permitted 180memory allocation (if Boost.Regex is configured in non-recursive mode). 181 182[*Returns]: *this. 183 184 185[#boost_regex.regex_iterator.op_inc2] 186 187 regex_iterator operator++(int); 188 189[*Effects]: constructs a copy result of `*this`, then calls `++(*this)`. 190 191[*Returns]: result. 192 193[#boost_regex.regex_iterator.make] 194 195 template <class charT, class traits> 196 regex_iterator<const charT*, charT, traits> 197 make_regex_iterator(const charT* p, const basic_regex<charT, traits>& e, 198 regex_constants::match_flag_type m = regex_constants::match_default); 199 200 template <class charT, class traits, class ST, class SA> 201 regex_iterator<typename std::basic_string<charT, ST, SA>::const_iterator, charT, traits> 202 make_regex_iterator(const std::basic_string<charT, ST, SA>& p, 203 const basic_regex<charT, traits>& e, 204 regex_constants::match_flag_type m = regex_constants::match_default); 205 206[*Effects]: returns an iterator that enumerates all occurrences of expression /e/ 207in text /p/ using [match_flag_type] /m/. 208 209[h4 Examples] 210 211The following example takes a C++ source file and builds up an index of class 212names, and the location of that class in the file. 213 214 #include <string> 215 #include <map> 216 #include <fstream> 217 #include <iostream> 218 #include <boost/regex.hpp> 219 220 using namespace std; 221 222 // purpose: 223 // takes the contents of a file in the form of a string 224 // and searches for all the C++ class definitions, storing 225 // their locations in a map of strings/int's 226 227 typedef std::map<std::string, std::string::difference_type, std::less<std::string> > map_type; 228 229 const char* re = 230 // possibly leading whitespace: 231 "^[[:space:]]*" 232 // possible template declaration: 233 "(template[[:space:]]*<[^;:{]+>[[:space:]]*)?" 234 // class or struct: 235 "(class|struct)[[:space:]]*" 236 // leading declspec macros etc: 237 "(" 238 "\\<\\w+\\>" 239 "(" 240 "[[:blank:]]*\\([^)]*\\)" 241 ")?" 242 "[[:space:]]*" 243 ")*" 244 // the class name 245 "(\\<\\w*\\>)[[:space:]]*" 246 // template specialisation parameters 247 "(<[^;:{]+>)?[[:space:]]*" 248 // terminate in { or : 249 "(\\{|:[^;\\{()]*\\{)"; 250 251 252 boost::regex expression(re); 253 map_type class_index; 254 255 bool regex_callback(const boost::match_results<std::string::const_iterator>& what) 256 { 257 // what[0] contains the whole string 258 // what[5] contains the class name. 259 // what[6] contains the template specialisation if any. 260 // add class name and position to map: 261 class_index[what[5].str() + what[6].str()] = what.position(5); 262 return true; 263 } 264 265 void load_file(std::string& s, std::istream& is) 266 { 267 s.erase(); 268 s.reserve(is.rdbuf()->in_avail()); 269 char c; 270 while(is.get(c)) 271 { 272 if(s.capacity() == s.size()) 273 s.reserve(s.capacity() * 3); 274 s.append(1, c); 275 } 276 } 277 278 int main(int argc, const char** argv) 279 { 280 std::string text; 281 for(int i = 1; i < argc; ++i) 282 { 283 cout << "Processing file " << argv[i] << endl; 284 std::ifstream fs(argv[i]); 285 load_file(text, fs); 286 // construct our iterators: 287 boost::sregex_iterator m1(text.begin(), text.end(), expression); 288 boost::sregex_iterator m2; 289 std::for_each(m1, m2, ®ex_callback); 290 // copy results: 291 cout << class_index.size() << " matches found" << endl; 292 map_type::iterator c, d; 293 c = class_index.begin(); 294 d = class_index.end(); 295 while(c != d) 296 { 297 cout << "class \"" << (*c).first << "\" found at index: " << (*c).second << endl; 298 ++c; 299 } 300 class_index.erase(class_index.begin(), class_index.end()); 301 } 302 return 0; 303 } 304 305 306[endsect] 307 308