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_grep regex_grep (Deprecated)] 10 11The algorithm `regex_grep` is deprecated in favor of [regex_iterator] 12which provides a more convenient and standard library friendly interface. 13 14The following documentation is taken unchanged from the previous boost 15release, and will not be updated in future. 16 17 #include <boost/regex.hpp> 18 19`regex_grep` allows you to search through a bidirectional-iterator range and 20locate all the (non-overlapping) matches with a given regular expression. 21The function is declared as: 22 23 template <class Predicate, class iterator, class charT, class traits> 24 unsigned int regex_grep(Predicate foo, 25 iterator first, 26 iterator last, 27 const basic_regex<charT, traits>& e, 28 boost::match_flag_type flags = match_default) 29 30The library also defines the following convenience versions, which take 31either a `const charT*`, or a `const std::basic_string<>&` in place of a 32pair of iterators. 33 34 template <class Predicate, class charT, class traits> 35 unsigned int regex_grep(Predicate foo, 36 const charT* str, 37 const basic_regex<charT, traits>& e, 38 boost::match_flag_type flags = match_default); 39 40 template <class Predicate, class ST, class SA, class charT, class traits> 41 unsigned int regex_grep(Predicate foo, 42 const std::basic_string<charT, ST, SA>& s, 43 const basic_regex<charT, traits>& e, 44 boost::match_flag_type flags = match_default); 45 46The parameters for the primary version of `regex_grep` have the following meanings: 47 48foo: A predicate function object or function pointer, see below for more information. 49 50first: The start of the range to search. 51 52last: The end of the range to search. 53 54e: The regular expression to search for. 55 56flags: The flags that determine how matching is carried out, one of the match_flags enumerators. 57 58 59The algorithm finds all of the non-overlapping matches of the expression /e/, 60for each match it fills a `match_results<iterator>` structure, which 61contains information on what matched, and calls the predicate /foo/, passing the 62`match_results<iterator>` as a single argument. If the predicate returns 63/true/, then the grep operation continues, otherwise it terminates 64without searching for further matches. The function returns the number 65of matches found. 66 67The general form of the predicate is: 68 69 struct grep_predicate 70 { 71 bool operator()(const match_results<iterator_type>& m); 72 }; 73 74For example the regular expression "a\*b" would find one match in the string 75"aaaaab" and two in the string "aaabb". 76 77Remember this algorithm can be used for a lot more than implementing a 78version of grep, the predicate can be and do anything that you want, 79grep utilities would output the results to the screen, another program could 80index a file based on a regular expression and store a set of bookmarks in a list, 81or a text file conversion utility would output to file. The results of one 82`regex_grep` can even be chained into another `regex_grep` to create recursive parsers. 83 84The algorithm may throw `std::runtime_error` if the complexity of matching the 85expression against an /N/ character string begins to exceed O(N[super 2]), or 86if the program runs out of stack space while matching the expression 87(if Boost.Regex is configured in recursive mode), or if the matcher 88exhausts it's permitted memory allocation (if Boost.Regex is configured in 89non-recursive mode). 90 91Example: convert the example from [regex_search] to use `regex_grep` instead: 92 93 #include <string> 94 #include <map> 95 #include <boost/regex.hpp> 96 97 // IndexClasses: 98 // takes the contents of a file in the form of a string 99 // and searches for all the C++ class definitions, storing 100 // their locations in a map of strings/int's 101 typedef std::map<std::string, int, std::less<std::string> > map_type; 102 103 const char* re = 104 // possibly leading whitespace: 105 "^[[:space:]]*" 106 // possible template declaration: 107 "(template[[:space:]]*<[^;:{]+>[[:space:]]*)?" 108 // class or struct: 109 "(class|struct)[[:space:]]*" 110 // leading declspec macros etc: 111 "(" 112 "\\<\\w+\\>" 113 "(" 114 "[[:blank:]]*\\([^)]*\\)" 115 ")?" 116 "[[:space:]]*" 117 ")*" 118 // the class name 119 "(\\<\\w*\\>)[[:space:]]*" 120 // template specialisation parameters 121 "(<[^;:{]+>)?[[:space:]]*" 122 // terminate in { or : 123 "(\\{|:[^;\\{()]*\\{)"; 124 125 boost::regex expression(re); 126 class IndexClassesPred 127 { 128 map_type& m; 129 std::string::const_iterator base; 130 public: 131 IndexClassesPred(map_type& a, std::string::const_iterator b) : m(a), base(b) {} 132 bool operator()(const smatch& what) 133 { 134 // what[0] contains the whole string 135 // what[5] contains the class name. 136 // what[6] contains the template specialisation if any. 137 // add class name and position to map: 138 m[std::string(what[5].first, what[5].second) + std::string(what[6].first, what[6].second)] = 139 what[5].first - base; 140 return true; 141 } 142 }; 143 void IndexClasses(map_type& m, const std::string& file) 144 { 145 std::string::const_iterator start, end; 146 start = file.begin(); 147 end = file.end(); 148 regex_grep(IndexClassesPred(m, start), start, end, expression); 149 } 150 151Example: Use `regex_grep` to call a global callback function: 152 153 #include <string> 154 #include <map> 155 #include <boost/regex.hpp> 156 157 // purpose: 158 // takes the contents of a file in the form of a string 159 // and searches for all the C++ class definitions, storing 160 // their locations in a map of strings/int's 161 typedef std::map<std::string, int, std::less<std::string> > map_type; 162 163 const char* re = 164 // possibly leading whitespace: 165 "^[[:space:]]*" 166 // possible template declaration: 167 "(template[[:space:]]*<[^;:{]+>[[:space:]]*)?" 168 // class or struct: 169 "(class|struct)[[:space:]]*" 170 // leading declspec macros etc: 171 "(" 172 "\\<\\w+\\>" 173 "(" 174 "[[:blank:]]*\\([^)]*\\)" 175 ")?" 176 "[[:space:]]*" 177 ")*" 178 // the class name 179 "(\\<\\w*\\>)[[:space:]]*" 180 // template specialisation parameters 181 "(<[^;:{]+>)?[[:space:]]*" 182 // terminate in { or : 183 "(\\{|:[^;\\{()]*\\{)"; 184 185 boost::regex expression(re); 186 map_type class_index; 187 std::string::const_iterator base; 188 189 bool grep_callback(const boost::smatch& what) 190 { 191 // what[0] contains the whole string 192 // what[5] contains the class name. 193 // what[6] contains the template specialisation if any. 194 // add class name and position to map: 195 class_index[std::string(what[5].first, what[5].second) + std::string(what[6].first, what[6].second)] = 196 what[5].first - base; 197 return true; 198 } 199 void IndexClasses(const std::string& file) 200 { 201 std::string::const_iterator start, end; 202 start = file.begin(); 203 end = file.end(); 204 base = start; 205 regex_grep(grep_callback, start, end, expression, match_default); 206 } 207 208 209Example: use `regex_grep` to call a class member function, use the standard 210library adapters `std::mem_fun` and `std::bind1st` to convert the member 211function into a predicate: 212 213 #include <string> 214 #include <map> 215 #include <boost/regex.hpp> 216 #include <functional> 217 // purpose: 218 // takes the contents of a file in the form of a string 219 // and searches for all the C++ class definitions, storing 220 // their locations in a map of strings/int's 221 222 typedef std::map<std::string, int, std::less<std::string> > map_type; 223 class class_index 224 { 225 boost::regex expression; 226 map_type index; 227 std::string::const_iterator base; 228 bool grep_callback(boost::smatch what); 229 public: 230 void IndexClasses(const std::string& file); 231 class_index() 232 : index(), 233 expression("^(template[[:space:]]*<[^;:{]+>[[:space:]]*)?" 234 "(class|struct)[[:space:]]*(\\<\\w+\\>([[:blank:]]*\\([^)]*\\))?" 235 "[[:space:]]*)*(\\<\\w*\\>)[[:space:]]*(<[^;:{]+>[[:space:]]*)?" 236 "(\\{|:[^;\\{()]*\\{)" 237 ){} 238 }; 239 bool class_index::grep_callback(boost::smatch what) 240 { 241 // what[0] contains the whole string 242 // what[5] contains the class name. 243 // what[6] contains the template specialisation if any. 244 // add class name and position to map: 245 index[std::string(what[5].first, what[5].second) + std::string(what[6].first, what[6].second)] = 246 what[5].first - base; 247 return true; 248 } 249 250 void class_index::IndexClasses(const std::string& file) 251 { 252 std::string::const_iterator start, end; 253 start = file.begin(); 254 end = file.end(); 255 base = start; 256 regex_grep(std::bind1st(std::mem_fun(&class_index::grep_callback), this), 257 start, 258 end, 259 expression); 260 } 261 262 263Finally, C++ Builder users can use C++ Builder's closure type as a callback argument: 264 265 #include <string> 266 #include <map> 267 #include <boost/regex.hpp> 268 #include <functional> 269 // purpose: 270 // takes the contents of a file in the form of a string 271 // and searches for all the C++ class definitions, storing 272 // their locations in a map of strings/int's 273 274 typedef std::map<std::string, int, std::less<std::string> > map_type; 275 class class_index 276 { 277 boost::regex expression; 278 map_type index; 279 std::string::const_iterator base; 280 typedef boost::smatch arg_type; 281 bool grep_callback(const arg_type& what); 282 public: 283 typedef bool (__closure* grep_callback_type)(const arg_type&); 284 void IndexClasses(const std::string& file); 285 class_index() 286 : index(), 287 expression("^(template[[:space:]]*<[^;:{]+>[[:space:]]*)?" 288 "(class|struct)[[:space:]]*(\\<\\w+\\>([[:blank:]]*\\([^)]*\\))?" 289 "[[:space:]]*)*(\\<\\w*\\>)[[:space:]]*(<[^;:{]+>[[:space:]]*)?" 290 "(\\{|:[^;\\{()]*\\{)" 291 ){} 292 }; 293 294 bool class_index::grep_callback(const arg_type& what) 295 { 296 // what[0] contains the whole string 297 // what[5] contains the class name. 298 // what[6] contains the template specialisation if any. 299 // add class name and position to map: 300 index[std::string(what[5].first, what[5].second) + std::string(what[6].first, what[6].second)] = 301 what[5].first - base; 302 return true; 303 } 304 305 void class_index::IndexClasses(const std::string& file) 306 { 307 std::string::const_iterator start, end; 308 start = file.begin(); 309 end = file.end(); 310 base = start; 311 class_index::grep_callback_type cl = &(this->grep_callback); 312 regex_grep(cl, 313 start, 314 end, 315 expression); 316 } 317 318 319[endsect] 320 321