]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 | ||
11 | The algorithm `regex_grep` is deprecated in favor of [regex_iterator] | |
12 | which provides a more convenient and standard library friendly interface. | |
13 | ||
14 | The following documentation is taken unchanged from the previous boost | |
15 | release, 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 | |
20 | locate all the (non-overlapping) matches with a given regular expression. | |
21 | The 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 | ||
30 | The library also defines the following convenience versions, which take | |
31 | either a `const charT*`, or a `const std::basic_string<>&` in place of a | |
32 | pair 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 | ||
46 | The parameters for the primary version of `regex_grep` have the following meanings: | |
47 | ||
48 | foo: A predicate function object or function pointer, see below for more information. | |
49 | ||
50 | first: The start of the range to search. | |
51 | ||
52 | last: The end of the range to search. | |
53 | ||
54 | e: The regular expression to search for. | |
55 | ||
56 | flags: The flags that determine how matching is carried out, one of the match_flags enumerators. | |
57 | ||
58 | ||
59 | The algorithm finds all of the non-overlapping matches of the expression /e/, | |
60 | for each match it fills a `match_results<iterator>` structure, which | |
61 | contains 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 | |
64 | without searching for further matches. The function returns the number | |
65 | of matches found. | |
66 | ||
67 | The general form of the predicate is: | |
68 | ||
69 | struct grep_predicate | |
70 | { | |
71 | bool operator()(const match_results<iterator_type>& m); | |
72 | }; | |
73 | ||
74 | For example the regular expression "a\*b" would find one match in the string | |
75 | "aaaaab" and two in the string "aaabb". | |
76 | ||
77 | Remember this algorithm can be used for a lot more than implementing a | |
78 | version of grep, the predicate can be and do anything that you want, | |
79 | grep utilities would output the results to the screen, another program could | |
80 | index a file based on a regular expression and store a set of bookmarks in a list, | |
81 | or 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 | ||
84 | The algorithm may throw `std::runtime_error` if the complexity of matching the | |
85 | expression against an /N/ character string begins to exceed O(N[super 2]), or | |
86 | if the program runs out of stack space while matching the expression | |
87 | (if Boost.Regex is configured in recursive mode), or if the matcher | |
88 | exhausts it's permitted memory allocation (if Boost.Regex is configured in | |
89 | non-recursive mode). | |
90 | ||
91 | Example: 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 | ||
151 | Example: 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 | ||
209 | Example: use `regex_grep` to call a class member function, use the standard | |
210 | library adapters `std::mem_fun` and `std::bind1st` to convert the member | |
211 | function 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 | ||
263 | Finally, 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 |