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