1 ///////////////////////////////////////////////////////////////////////////////
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)
10 #include <boost/xpressive/xpressive.hpp>
12 using namespace boost::xpressive;
14 ///////////////////////////////////////////////////////////////////////////////
15 // Displays nested results to std::cout with indenting
17 // Display a tree of nested results
19 // Here is a helper class to demonstrate how you might display a tree of nested results:
20 struct output_nested_results
24 output_nested_results(int tabs = 0)
29 template< typename BidiIterT >
30 void operator ()( match_results< BidiIterT > const &what ) const
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 );
38 std::cout << what[0] << '\n';
40 // output any nested matches
42 what.nested_results().begin(),
43 what.nested_results().end(),
44 output_nested_results( tabs_ + 1 ) );
48 ///////////////////////////////////////////////////////////////////////////////
49 // See if a whole string matches a regex
51 // This program outputs the following:
59 std::string hello( "hello world!" );
61 sregex rex = sregex::compile( "(\\w+) (\\w+)!" );
64 if( regex_match( hello, what, rex ) )
66 std::cout << what[0] << '\n'; // whole match
67 std::cout << what[1] << '\n'; // first capture
68 std::cout << what[2] << '\n'; // second capture
72 ///////////////////////////////////////////////////////////////////////////////
73 // See if a string contains a sub-string that matches a regex
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<>.
78 // This program outputs the following:
88 char const *str = "I was born on 5/30/1973 at 7am.";
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);
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.
101 if( regex_search( str, what, date ) )
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
111 ///////////////////////////////////////////////////////////////////////////////
112 // Replace all sub-strings that match a regex
114 // The following program finds dates in a string and marks them up with pseudo-HTML.
116 // This program outputs the following:
118 // I was born on <date>5/30/1973</date> at 7am.
122 std::string str( "I was born on 5/30/1973 at 7am." );
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})" );
127 // As in Perl, $& is a reference to the sub-string that matched the regex
128 std::string format( "<date>$&</date>" );
130 str = regex_replace( str, date, format );
131 std::cout << str << '\n';
134 ///////////////////////////////////////////////////////////////////////////////
135 // Find all the sub-strings that match a regex and step through them one at a time
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.
140 // This program outputs the following:
149 #ifndef BOOST_XPRESSIVE_NO_WREGEX
150 std::wstring str( L"This is his face." );
153 wsregex token = +alnum;
155 wsregex_iterator cur( str.begin(), str.end(), token );
156 wsregex_iterator end;
158 for( ; cur != end; ++cur )
160 wsmatch const &what = *cur;
161 std::wcout << what[0] << L'\n';
166 ///////////////////////////////////////////////////////////////////////////////
167 // Split a string into tokens that each match a regex
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<>.
172 // This program outputs the following:
183 std::string str( "Eric: 4:40, Karl: 3:35, Francesca: 2:32" );
186 sregex time = sregex::compile( "(\\d):(\\d\\d)" );
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 };
193 sregex_token_iterator cur( str.begin(), str.end(), time, subs );
194 sregex_token_iterator end;
196 for( ; cur != end; ++cur )
198 std::cout << *cur << '\n';
202 ///////////////////////////////////////////////////////////////////////////////
203 // Split a string using a regex as a delimiter
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.
209 // This program outputs the following:
211 // {Now }{is the time }{for all good men}{ to come to the aid of their}{ country.}
215 std::string str( "Now <bold>is the time <i>for all good men</i> to come to the aid of their</bold> country." );
218 sregex html = '<' >> optional('/') >> +_w >> '>';
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;
225 for( ; cur != end; ++cur )
227 std::cout << '{' << *cur << '}';
232 ///////////////////////////////////////////////////////////////////////////////
236 std::cout << "\n\nExample 1:\n\n";
239 std::cout << "\n\nExample 2:\n\n";
242 std::cout << "\n\nExample 3:\n\n";
245 std::cout << "\n\nExample 4:\n\n";
248 std::cout << "\n\nExample 5:\n\n";
251 std::cout << "\n\nExample 6:\n\n";
254 std::cout << "\n\n" << std::flush;