main.cpp 7.1 KB

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