• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1[/
2 / Copyright (c) 2008 Eric Niebler
3 /
4 / Distributed under the Boost Software License, Version 1.0. (See accompanying
5 / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 /]
7
8[section Examples]
9
10Below you can find six complete sample programs.
11\n
12
13----
14
15[h4 See if a whole string matches a regex]
16
17This is the example from the Introduction. It is reproduced here for your convenience.
18
19    #include <iostream>
20    #include <boost/xpressive/xpressive.hpp>
21
22    using namespace boost::xpressive;
23
24    int main()
25    {
26        std::string hello( "hello world!" );
27
28        sregex rex = sregex::compile( "(\\w+) (\\w+)!" );
29        smatch what;
30
31        if( regex_match( hello, what, rex ) )
32        {
33            std::cout << what[0] << '\n'; // whole match
34            std::cout << what[1] << '\n'; // first capture
35            std::cout << what[2] << '\n'; // second capture
36        }
37
38        return 0;
39    }
40
41This program outputs the following:
42
43[pre
44hello world!
45hello
46world
47]
48\n
49[link boost_xpressive.user_s_guide.examples top]
50
51----
52
53[h4 See if a string contains a sub-string that matches a regex]
54
55Notice in this example how we use custom `mark_tag`s to make the pattern more readable.
56We can use the `mark_tag`s later to index into the _match_results_.
57
58    #include <iostream>
59    #include <boost/xpressive/xpressive.hpp>
60
61    using namespace boost::xpressive;
62
63    int main()
64    {
65        char const *str = "I was born on 5/30/1973 at 7am.";
66
67        // define some custom mark_tags with names more meaningful than s1, s2, etc.
68        mark_tag day(1), month(2), year(3), delim(4);
69
70        // this regex finds a date
71        cregex date = (month= repeat<1,2>(_d))           // find the month ...
72                   >> (delim= (set= '/','-'))            // followed by a delimiter ...
73                   >> (day=   repeat<1,2>(_d)) >> delim  // and a day followed by the same delimiter ...
74                   >> (year=  repeat<1,2>(_d >> _d));    // and the year.
75
76        cmatch what;
77
78        if( regex_search( str, what, date ) )
79        {
80            std::cout << what[0]     << '\n'; // whole match
81            std::cout << what[day]   << '\n'; // the day
82            std::cout << what[month] << '\n'; // the month
83            std::cout << what[year]  << '\n'; // the year
84            std::cout << what[delim] << '\n'; // the delimiter
85        }
86
87        return 0;
88    }
89
90This program outputs the following:
91
92[pre
935/30/1973
9430
955
961973
97/
98]
99\n
100[link boost_xpressive.user_s_guide.examples top]
101
102----
103
104[h4 Replace all sub-strings that match a regex]
105
106The following program finds dates in a string and marks them up with pseudo-HTML.
107
108    #include <iostream>
109    #include <boost/xpressive/xpressive.hpp>
110
111    using namespace boost::xpressive;
112
113    int main()
114    {
115        std::string str( "I was born on 5/30/1973 at 7am." );
116
117        // essentially the same regex as in the previous example, but using a dynamic regex
118        sregex date = sregex::compile( "(\\d{1,2})([/-])(\\d{1,2})\\2((?:\\d{2}){1,2})" );
119
120        // As in Perl, $& is a reference to the sub-string that matched the regex
121        std::string format( "<date>$&</date>" );
122
123        str = regex_replace( str, date, format );
124        std::cout << str << '\n';
125
126        return 0;
127    }
128
129This program outputs the following:
130
131[pre
132I was born on <date>5/30/1973</date> at 7am.
133]
134\n
135[link boost_xpressive.user_s_guide.examples top]
136
137----
138
139[h4 Find all the sub-strings that match a regex and step through them one at a time]
140
141The following program finds the words in a wide-character string.
142It uses `wsregex_iterator`. Notice that dereferencing a `wsregex_iterator`
143yields a `wsmatch` object.
144
145    #include <iostream>
146    #include <boost/xpressive/xpressive.hpp>
147
148    using namespace boost::xpressive;
149
150    int main()
151    {
152        std::wstring str( L"This is his face." );
153
154        // find a whole word
155        wsregex token = +alnum;
156
157        wsregex_iterator cur( str.begin(), str.end(), token );
158        wsregex_iterator end;
159
160        for( ; cur != end; ++cur )
161        {
162            wsmatch const &what = *cur;
163            std::wcout << what[0] << L'\n';
164        }
165
166        return 0;
167    }
168
169This program outputs the following:
170
171[pre
172This
173is
174his
175face
176]
177\n
178[link boost_xpressive.user_s_guide.examples top]
179
180----
181
182[h4 Split a string into tokens that each match a regex]
183
184The following program finds race times in a string and displays first
185the minutes and then the seconds. It uses _regex_token_iterator_.
186
187    #include <iostream>
188    #include <boost/xpressive/xpressive.hpp>
189
190    using namespace boost::xpressive;
191
192    int main()
193    {
194        std::string str( "Eric: 4:40, Karl: 3:35, Francesca: 2:32" );
195
196        // find a race time
197        sregex time = sregex::compile( "(\\d):(\\d\\d)" );
198
199        // for each match, the token iterator should first take the value of
200        // the first marked sub-expression followed by the value of the second
201        // marked sub-expression
202        int const subs[] = { 1, 2 };
203
204        sregex_token_iterator cur( str.begin(), str.end(), time, subs );
205        sregex_token_iterator end;
206
207        for( ; cur != end; ++cur )
208        {
209            std::cout << *cur << '\n';
210        }
211
212        return 0;
213    }
214
215This program outputs the following:
216
217[pre
2184
21940
2203
22135
2222
22332
224]
225\n
226[link boost_xpressive.user_s_guide.examples top]
227
228----
229
230[h4 Split a string using a regex as a delimiter]
231
232The following program takes some text that has been marked up with html and strips
233out the mark-up. It uses a regex that matches an HTML tag and a _regex_token_iterator_
234that returns the parts of the string that do ['not] match the regex.
235
236    #include <iostream>
237    #include <boost/xpressive/xpressive.hpp>
238
239    using namespace boost::xpressive;
240
241    int main()
242    {
243        std::string str( "Now <bold>is the time <i>for all good men</i> to come to the aid of their</bold> country." );
244
245        // find a HTML tag
246        sregex html = '<' >> optional('/') >> +_w >> '>';
247
248        // the -1 below directs the token iterator to display the parts of
249        // the string that did NOT match the regular expression.
250        sregex_token_iterator cur( str.begin(), str.end(), html, -1 );
251        sregex_token_iterator end;
252
253        for( ; cur != end; ++cur )
254        {
255            std::cout << '{' << *cur << '}';
256        }
257        std::cout << '\n';
258
259        return 0;
260    }
261
262This program outputs the following:
263
264[pre
265{Now }{is the time }{for all good men}{ to come to the aid of their}{ country.}
266]
267\n
268[link boost_xpressive.user_s_guide.examples top]
269
270----
271
272[h4 Display a tree of nested results]
273
274Here is a helper class to demonstrate how you might display a tree of nested results:
275
276    // Displays nested results to std::cout with indenting
277    struct output_nested_results
278    {
279        int tabs_;
280
281        output_nested_results( int tabs = 0 )
282            : tabs_( tabs )
283        {
284        }
285
286        template< typename BidiIterT >
287        void operator ()( match_results< BidiIterT > const &what ) const
288        {
289            // first, do some indenting
290            typedef typename std::iterator_traits< BidiIterT >::value_type char_type;
291            char_type space_ch = char_type(' ');
292            std::fill_n( std::ostream_iterator<char_type>( std::cout ), tabs_ * 4, space_ch );
293
294            // output the match
295            std::cout << what[0] << '\n';
296
297            // output any nested matches
298            std::for_each(
299                what.nested_results().begin(),
300                what.nested_results().end(),
301                output_nested_results( tabs_ + 1 ) );
302        }
303    };
304
305[link boost_xpressive.user_s_guide.examples top]
306
307[endsect]
308