• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, &regex_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