]>
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_iterator regex_iterator] | |
10 | ||
11 | The iterator type [regex_iterator] will enumerate all of the regular expression | |
12 | matches found in some sequence: dereferencing a [regex_iterator] yields a | |
13 | reference 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 | ||
63 | A [regex_iterator] is constructed from a pair of iterators, and enumerates | |
64 | all 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 | |
79 | the expression /re/, within the sequence \[a,b), and found using [match_flag_type] /m/. | |
80 | The object /re/ must exist for the lifetime of the [regex_iterator]. | |
81 | ||
82 | [*Throws]: `std::runtime_error` if the complexity of matching the expression | |
83 | against an N character string begins to exceed O(N[super 2]), or if the program | |
84 | runs out of stack space while matching the expression (if Boost.Regex is | |
85 | configured in recursive mode), or if the matcher exhausts its permitted | |
86 | memory 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 | |
125 | to 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 | |
170 | the end of sequence iterator if none if found. When the last match found | |
171 | matched a zero length string, then the [regex_iterator] will find the next match as | |
172 | follows: if there exists a non-zero length match that starts at the same | |
173 | location as the last one, then returns it, otherwise starts looking for the | |
174 | next (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 | |
177 | against an N character string begins to exceed O(N[super 2]), or if the | |
178 | program runs out of stack space while matching the expression (if Boost.Regex is | |
179 | configured in recursive mode), or if the matcher exhausts its permitted | |
180 | memory 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/ | |
207 | in text /p/ using [match_flag_type] /m/. | |
208 | ||
209 | [h4 Examples] | |
210 | ||
211 | The following example takes a C++ source file and builds up an index of class | |
212 | names, 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 |