regex_algorithms.hpp 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993
  1. ///////////////////////////////////////////////////////////////////////////////
  2. /// \file regex_algorithms.hpp
  3. /// Contains the regex_match(), regex_search() and regex_replace() algorithms.
  4. //
  5. // Copyright 2008 Eric Niebler. Distributed under the Boost
  6. // Software License, Version 1.0. (See accompanying file
  7. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  8. #ifndef BOOST_XPRESSIVE_ALGORITHMS_HPP_EAN_10_04_2005
  9. #define BOOST_XPRESSIVE_ALGORITHMS_HPP_EAN_10_04_2005
  10. // MS compatible compilers support #pragma once
  11. #if defined(_MSC_VER)
  12. # pragma once
  13. #endif
  14. #include <string>
  15. #include <iterator>
  16. #include <boost/mpl/or.hpp>
  17. #include <boost/range/end.hpp>
  18. #include <boost/range/begin.hpp>
  19. #include <boost/mpl/identity.hpp>
  20. #include <boost/utility/enable_if.hpp>
  21. #include <boost/type_traits/add_const.hpp>
  22. #include <boost/type_traits/is_pointer.hpp>
  23. #include <boost/type_traits/remove_const.hpp>
  24. #include <boost/xpressive/match_results.hpp>
  25. #include <boost/xpressive/detail/detail_fwd.hpp>
  26. #include <boost/xpressive/detail/core/state.hpp>
  27. #include <boost/xpressive/detail/utility/save_restore.hpp>
  28. /// INTERNAL ONLY
  29. ///
  30. #define BOOST_XPR_NONDEDUCED_TYPE_(x) typename mpl::identity<x>::type
  31. namespace boost { namespace xpressive
  32. {
  33. ///////////////////////////////////////////////////////////////////////////////
  34. // regex_match
  35. ///////////////////////////////////////////////////////////////////////////////
  36. namespace detail
  37. {
  38. ///////////////////////////////////////////////////////////////////////////////
  39. // regex_match_impl
  40. template<typename BidiIter>
  41. inline bool regex_match_impl
  42. (
  43. BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) begin
  44. , BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) end
  45. , match_results<BidiIter> &what
  46. , basic_regex<BidiIter> const &re
  47. , regex_constants::match_flag_type flags = regex_constants::match_default
  48. )
  49. {
  50. typedef detail::core_access<BidiIter> access;
  51. BOOST_ASSERT(0 != re.regex_id());
  52. // the state object holds matching state and
  53. // is passed by reference to all the matchers
  54. detail::match_state<BidiIter> state(begin, end, what, *access::get_regex_impl(re), flags);
  55. state.flags_.match_all_ = true;
  56. state.sub_match(0).begin_ = begin;
  57. if(access::match(re, state))
  58. {
  59. access::set_prefix_suffix(what, begin, end);
  60. return true;
  61. }
  62. // handle partial matches
  63. else if(state.found_partial_match_ && 0 != (flags & regex_constants::match_partial))
  64. {
  65. state.set_partial_match();
  66. return true;
  67. }
  68. access::reset(what);
  69. return false;
  70. }
  71. } // namespace detail
  72. /// \brief See if a regex matches a sequence from beginning to end.
  73. ///
  74. /// Determines whether there is an exact match between the regular expression \c re,
  75. /// and all of the sequence <tt>[begin, end)</tt>.
  76. ///
  77. /// \pre Type \c BidiIter meets the requirements of a Bidirectional Iterator (24.1.4).
  78. /// \pre <tt>[begin,end)</tt> denotes a valid iterator range.
  79. /// \param begin The beginning of the sequence.
  80. /// \param end The end of the sequence.
  81. /// \param what The \c match_results struct into which the sub_matches will be written
  82. /// \param re The regular expression object to use
  83. /// \param flags Optional match flags, used to control how the expression is matched
  84. /// against the sequence. (See \c match_flag_type.)
  85. /// \return \c true if a match is found, \c false otherwise
  86. /// \throw regex_error on stack exhaustion
  87. template<typename BidiIter>
  88. inline bool regex_match
  89. (
  90. BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) begin
  91. , BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) end
  92. , match_results<BidiIter> &what
  93. , basic_regex<BidiIter> const &re
  94. , regex_constants::match_flag_type flags = regex_constants::match_default
  95. )
  96. {
  97. typedef detail::core_access<BidiIter> access;
  98. if(0 == re.regex_id())
  99. {
  100. access::reset(what);
  101. return false;
  102. }
  103. return detail::regex_match_impl(begin, end, what, re, flags);
  104. }
  105. /// \overload
  106. ///
  107. template<typename BidiIter>
  108. inline bool regex_match
  109. (
  110. BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) begin
  111. , BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) end
  112. , basic_regex<BidiIter> const &re
  113. , regex_constants::match_flag_type flags = regex_constants::match_default
  114. )
  115. {
  116. if(0 == re.regex_id())
  117. {
  118. return false;
  119. }
  120. // BUGBUG this is inefficient
  121. match_results<BidiIter> what;
  122. return detail::regex_match_impl(begin, end, what, re, flags);
  123. }
  124. /// \overload
  125. ///
  126. template<typename Char>
  127. inline bool regex_match
  128. (
  129. BOOST_XPR_NONDEDUCED_TYPE_(Char) *begin
  130. , match_results<Char *> &what
  131. , basic_regex<Char *> const &re
  132. , regex_constants::match_flag_type flags = regex_constants::match_default
  133. )
  134. {
  135. typedef detail::core_access<Char *> access;
  136. if(0 == re.regex_id())
  137. {
  138. access::reset(what);
  139. return false;
  140. }
  141. // BUGBUG this is inefficient
  142. typedef typename remove_const<Char>::type char_type;
  143. Char *end = begin + std::char_traits<char_type>::length(begin);
  144. return detail::regex_match_impl(begin, end, what, re, flags);
  145. }
  146. /// \overload
  147. ///
  148. template<typename BidiRange, typename BidiIter>
  149. inline bool regex_match
  150. (
  151. BidiRange &rng
  152. , match_results<BidiIter> &what
  153. , basic_regex<BidiIter> const &re
  154. , regex_constants::match_flag_type flags = regex_constants::match_default
  155. , typename disable_if<detail::is_char_ptr<BidiRange> >::type * = 0
  156. )
  157. {
  158. typedef detail::core_access<BidiIter> access;
  159. if(0 == re.regex_id())
  160. {
  161. access::reset(what);
  162. return false;
  163. }
  164. // Note that the result iterator of the range must be convertible
  165. // to BidiIter here.
  166. BidiIter begin = boost::begin(rng), end = boost::end(rng);
  167. return detail::regex_match_impl(begin, end, what, re, flags);
  168. }
  169. /// \overload
  170. ///
  171. template<typename BidiRange, typename BidiIter>
  172. inline bool regex_match
  173. (
  174. BidiRange const &rng
  175. , match_results<BidiIter> &what
  176. , basic_regex<BidiIter> const &re
  177. , regex_constants::match_flag_type flags = regex_constants::match_default
  178. , typename disable_if<detail::is_char_ptr<BidiRange> >::type * = 0
  179. )
  180. {
  181. typedef detail::core_access<BidiIter> access;
  182. if(0 == re.regex_id())
  183. {
  184. access::reset(what);
  185. return false;
  186. }
  187. // Note that the result iterator of the range must be convertible
  188. // to BidiIter here.
  189. BidiIter begin = boost::begin(rng), end = boost::end(rng);
  190. return detail::regex_match_impl(begin, end, what, re, flags);
  191. }
  192. /// \overload
  193. ///
  194. template<typename Char>
  195. inline bool regex_match
  196. (
  197. BOOST_XPR_NONDEDUCED_TYPE_(Char) *begin
  198. , basic_regex<Char *> const &re
  199. , regex_constants::match_flag_type flags = regex_constants::match_default
  200. )
  201. {
  202. if(0 == re.regex_id())
  203. {
  204. return false;
  205. }
  206. // BUGBUG this is inefficient
  207. match_results<Char *> what;
  208. typedef typename remove_const<Char>::type char_type;
  209. Char *end = begin + std::char_traits<char_type>::length(begin);
  210. return detail::regex_match_impl(begin, end, what, re, flags);
  211. }
  212. /// \overload
  213. ///
  214. template<typename BidiRange, typename BidiIter>
  215. inline bool regex_match
  216. (
  217. BidiRange &rng
  218. , basic_regex<BidiIter> const &re
  219. , regex_constants::match_flag_type flags = regex_constants::match_default
  220. , typename disable_if<detail::is_char_ptr<BidiRange> >::type * = 0
  221. )
  222. {
  223. if(0 == re.regex_id())
  224. {
  225. return false;
  226. }
  227. // BUGBUG this is inefficient
  228. match_results<BidiIter> what;
  229. // Note that the result iterator of the range must be convertible
  230. // to BidiIter here.
  231. BidiIter begin = boost::begin(rng), end = boost::end(rng);
  232. return detail::regex_match_impl(begin, end, what, re, flags);
  233. }
  234. /// \overload
  235. ///
  236. template<typename BidiRange, typename BidiIter>
  237. inline bool regex_match
  238. (
  239. BidiRange const &rng
  240. , basic_regex<BidiIter> const &re
  241. , regex_constants::match_flag_type flags = regex_constants::match_default
  242. , typename disable_if<detail::is_char_ptr<BidiRange> >::type * = 0
  243. )
  244. {
  245. if(0 == re.regex_id())
  246. {
  247. return false;
  248. }
  249. // BUGBUG this is inefficient
  250. match_results<BidiIter> what;
  251. // Note that the result iterator of the range must be convertible
  252. // to BidiIter here.
  253. BidiIter begin = boost::begin(rng), end = boost::end(rng);
  254. return detail::regex_match_impl(begin, end, what, re, flags);
  255. }
  256. ///////////////////////////////////////////////////////////////////////////////
  257. // regex_search
  258. ///////////////////////////////////////////////////////////////////////////////
  259. namespace detail
  260. {
  261. ///////////////////////////////////////////////////////////////////////////////
  262. // regex_search_impl
  263. template<typename BidiIter>
  264. inline bool regex_search_impl
  265. (
  266. match_state<BidiIter> &state
  267. , basic_regex<BidiIter> const &re
  268. , bool not_initial_null = false
  269. )
  270. {
  271. typedef core_access<BidiIter> access;
  272. match_results<BidiIter> &what = *state.context_.results_ptr_;
  273. BOOST_ASSERT(0 != re.regex_id());
  274. bool const partial_ok = state.flags_.match_partial_;
  275. save_restore<bool> not_null(state.flags_.match_not_null_, state.flags_.match_not_null_ || not_initial_null);
  276. state.flags_.match_prev_avail_ = state.flags_.match_prev_avail_ || !state.bos();
  277. regex_impl<BidiIter> const &impl = *access::get_regex_impl(re);
  278. BidiIter const begin = state.cur_, end = state.end_;
  279. BidiIter &sub0begin = state.sub_match(0).begin_;
  280. sub0begin = state.cur_;
  281. // If match_continuous is set, we only need to check for a match at the current position
  282. if(state.flags_.match_continuous_)
  283. {
  284. if(access::match(re, state))
  285. {
  286. access::set_prefix_suffix(what, begin, end);
  287. return true;
  288. }
  289. // handle partial matches
  290. else if(partial_ok && state.found_partial_match_)
  291. {
  292. state.set_partial_match();
  293. return true;
  294. }
  295. }
  296. // If we have a finder, use it to find where a potential match can start
  297. else if(impl.finder_ && (!partial_ok || impl.finder_->ok_for_partial_matches()))
  298. {
  299. finder<BidiIter> const &find = *impl.finder_;
  300. if(find(state))
  301. {
  302. if(state.cur_ != begin)
  303. {
  304. not_null.restore();
  305. }
  306. do
  307. {
  308. sub0begin = state.cur_;
  309. if(access::match(re, state))
  310. {
  311. access::set_prefix_suffix(what, begin, end);
  312. return true;
  313. }
  314. // handle partial matches
  315. else if(partial_ok && state.found_partial_match_)
  316. {
  317. state.set_partial_match();
  318. return true;
  319. }
  320. BOOST_ASSERT(state.cur_ == sub0begin);
  321. not_null.restore();
  322. }
  323. while(state.cur_ != state.end_ && (++state.cur_, find(state)));
  324. }
  325. }
  326. // Otherwise, use brute force search at every position.
  327. else
  328. {
  329. for(;;)
  330. {
  331. if(access::match(re, state))
  332. {
  333. access::set_prefix_suffix(what, begin, end);
  334. return true;
  335. }
  336. // handle partial matches
  337. else if(partial_ok && state.found_partial_match_)
  338. {
  339. state.set_partial_match();
  340. return true;
  341. }
  342. else if(end == sub0begin)
  343. {
  344. break;
  345. }
  346. BOOST_ASSERT(state.cur_ == sub0begin);
  347. state.cur_ = ++sub0begin;
  348. not_null.restore();
  349. }
  350. }
  351. access::reset(what);
  352. return false;
  353. }
  354. } // namespace detail
  355. /// \brief Determines whether there is some sub-sequence within <tt>[begin,end)</tt>
  356. /// that matches the regular expression \c re.
  357. ///
  358. /// Determines whether there is some sub-sequence within <tt>[begin,end)</tt> that matches
  359. /// the regular expression \c re.
  360. ///
  361. /// \pre Type \c BidiIter meets the requirements of a Bidirectional Iterator (24.1.4).
  362. /// \pre <tt>[begin,end)</tt> denotes a valid iterator range.
  363. /// \param begin The beginning of the sequence
  364. /// \param end The end of the sequence
  365. /// \param what The \c match_results struct into which the sub_matches will be written
  366. /// \param re The regular expression object to use
  367. /// \param flags Optional match flags, used to control how the expression is matched against
  368. /// the sequence. (See \c match_flag_type.)
  369. /// \return \c true if a match is found, \c false otherwise
  370. /// \throw regex_error on stack exhaustion
  371. template<typename BidiIter>
  372. inline bool regex_search
  373. (
  374. BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) begin
  375. , BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) end
  376. , match_results<BidiIter> &what
  377. , basic_regex<BidiIter> const &re
  378. , regex_constants::match_flag_type flags = regex_constants::match_default
  379. )
  380. {
  381. typedef detail::core_access<BidiIter> access;
  382. // a default-constructed regex matches nothing
  383. if(0 == re.regex_id())
  384. {
  385. access::reset(what);
  386. return false;
  387. }
  388. // the state object holds matching state and
  389. // is passed by reference to all the matchers
  390. detail::match_state<BidiIter> state(begin, end, what, *access::get_regex_impl(re), flags);
  391. return detail::regex_search_impl(state, re);
  392. }
  393. /// \overload
  394. ///
  395. template<typename BidiIter>
  396. inline bool regex_search
  397. (
  398. BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) begin
  399. , BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) end
  400. , basic_regex<BidiIter> const &re
  401. , regex_constants::match_flag_type flags = regex_constants::match_default
  402. )
  403. {
  404. typedef detail::core_access<BidiIter> access;
  405. // a default-constructed regex matches nothing
  406. if(0 == re.regex_id())
  407. {
  408. return false;
  409. }
  410. // BUGBUG this is inefficient
  411. match_results<BidiIter> what;
  412. // the state object holds matching state and
  413. // is passed by reference to all the matchers
  414. detail::match_state<BidiIter> state(begin, end, what, *access::get_regex_impl(re), flags);
  415. return detail::regex_search_impl(state, re);
  416. }
  417. /// \overload
  418. ///
  419. template<typename Char>
  420. inline bool regex_search
  421. (
  422. BOOST_XPR_NONDEDUCED_TYPE_(Char) *begin
  423. , match_results<Char *> &what
  424. , basic_regex<Char *> const &re
  425. , regex_constants::match_flag_type flags = regex_constants::match_default
  426. )
  427. {
  428. typedef detail::core_access<Char *> access;
  429. // a default-constructed regex matches nothing
  430. if(0 == re.regex_id())
  431. {
  432. access::reset(what);
  433. return false;
  434. }
  435. // BUGBUG this is inefficient
  436. typedef typename remove_const<Char>::type char_type;
  437. Char *end = begin + std::char_traits<char_type>::length(begin);
  438. // the state object holds matching state and
  439. // is passed by reference to all the matchers
  440. detail::match_state<Char *> state(begin, end, what, *access::get_regex_impl(re), flags);
  441. return detail::regex_search_impl(state, re);
  442. }
  443. /// \overload
  444. ///
  445. template<typename BidiRange, typename BidiIter>
  446. inline bool regex_search
  447. (
  448. BidiRange &rng
  449. , match_results<BidiIter> &what
  450. , basic_regex<BidiIter> const &re
  451. , regex_constants::match_flag_type flags = regex_constants::match_default
  452. , typename disable_if<detail::is_char_ptr<BidiRange> >::type * = 0
  453. )
  454. {
  455. typedef detail::core_access<BidiIter> access;
  456. // a default-constructed regex matches nothing
  457. if(0 == re.regex_id())
  458. {
  459. access::reset(what);
  460. return false;
  461. }
  462. // Note that the result iterator of the range must be convertible
  463. // to BidiIter here.
  464. BidiIter begin = boost::begin(rng), end = boost::end(rng);
  465. // the state object holds matching state and
  466. // is passed by reference to all the matchers
  467. detail::match_state<BidiIter> state(begin, end, what, *access::get_regex_impl(re), flags);
  468. return detail::regex_search_impl(state, re);
  469. }
  470. /// \overload
  471. ///
  472. template<typename BidiRange, typename BidiIter>
  473. inline bool regex_search
  474. (
  475. BidiRange const &rng
  476. , match_results<BidiIter> &what
  477. , basic_regex<BidiIter> const &re
  478. , regex_constants::match_flag_type flags = regex_constants::match_default
  479. , typename disable_if<detail::is_char_ptr<BidiRange> >::type * = 0
  480. )
  481. {
  482. typedef detail::core_access<BidiIter> access;
  483. // a default-constructed regex matches nothing
  484. if(0 == re.regex_id())
  485. {
  486. access::reset(what);
  487. return false;
  488. }
  489. // Note that the result iterator of the range must be convertible
  490. // to BidiIter here.
  491. BidiIter begin = boost::begin(rng), end = boost::end(rng);
  492. // the state object holds matching state and
  493. // is passed by reference to all the matchers
  494. detail::match_state<BidiIter> state(begin, end, what, *access::get_regex_impl(re), flags);
  495. return detail::regex_search_impl(state, re);
  496. }
  497. /// \overload
  498. ///
  499. template<typename Char>
  500. inline bool regex_search
  501. (
  502. BOOST_XPR_NONDEDUCED_TYPE_(Char) *begin
  503. , basic_regex<Char *> const &re
  504. , regex_constants::match_flag_type flags = regex_constants::match_default
  505. )
  506. {
  507. typedef detail::core_access<Char *> access;
  508. // a default-constructed regex matches nothing
  509. if(0 == re.regex_id())
  510. {
  511. return false;
  512. }
  513. // BUGBUG this is inefficient
  514. match_results<Char *> what;
  515. // BUGBUG this is inefficient
  516. typedef typename remove_const<Char>::type char_type;
  517. Char *end = begin + std::char_traits<char_type>::length(begin);
  518. // the state object holds matching state and
  519. // is passed by reference to all the matchers
  520. detail::match_state<Char *> state(begin, end, what, *access::get_regex_impl(re), flags);
  521. return detail::regex_search_impl(state, re);
  522. }
  523. /// \overload
  524. ///
  525. template<typename BidiRange, typename BidiIter>
  526. inline bool regex_search
  527. (
  528. BidiRange &rng
  529. , basic_regex<BidiIter> const &re
  530. , regex_constants::match_flag_type flags = regex_constants::match_default
  531. , typename disable_if<detail::is_char_ptr<BidiRange> >::type * = 0
  532. )
  533. {
  534. typedef detail::core_access<BidiIter> access;
  535. // a default-constructed regex matches nothing
  536. if(0 == re.regex_id())
  537. {
  538. return false;
  539. }
  540. // BUGBUG this is inefficient
  541. match_results<BidiIter> what;
  542. // Note that the result iterator of the range must be convertible
  543. // to BidiIter here.
  544. BidiIter begin = boost::begin(rng), end = boost::end(rng);
  545. // the state object holds matching state and
  546. // is passed by reference to all the matchers
  547. detail::match_state<BidiIter> state(begin, end, what, *access::get_regex_impl(re), flags);
  548. return detail::regex_search_impl(state, re);
  549. }
  550. /// \overload
  551. ///
  552. template<typename BidiRange, typename BidiIter>
  553. inline bool regex_search
  554. (
  555. BidiRange const &rng
  556. , basic_regex<BidiIter> const &re
  557. , regex_constants::match_flag_type flags = regex_constants::match_default
  558. , typename disable_if<detail::is_char_ptr<BidiRange> >::type * = 0
  559. )
  560. {
  561. typedef detail::core_access<BidiIter> access;
  562. // a default-constructed regex matches nothing
  563. if(0 == re.regex_id())
  564. {
  565. return false;
  566. }
  567. // BUGBUG this is inefficient
  568. match_results<BidiIter> what;
  569. // Note that the result iterator of the range must be convertible
  570. // to BidiIter here.
  571. BidiIter begin = boost::begin(rng), end = boost::end(rng);
  572. // the state object holds matching state and
  573. // is passed by reference to all the matchers
  574. detail::match_state<BidiIter> state(begin, end, what, *access::get_regex_impl(re), flags);
  575. return detail::regex_search_impl(state, re);
  576. }
  577. ///////////////////////////////////////////////////////////////////////////////
  578. // regex_replace
  579. ///////////////////////////////////////////////////////////////////////////////
  580. namespace detail
  581. {
  582. ///////////////////////////////////////////////////////////////////////////////
  583. // regex_replace_impl
  584. template<typename OutIter, typename BidiIter, typename Formatter>
  585. inline OutIter regex_replace_impl
  586. (
  587. OutIter out
  588. , BidiIter begin
  589. , BidiIter end
  590. , basic_regex<BidiIter> const &re
  591. , Formatter const &format
  592. , regex_constants::match_flag_type flags = regex_constants::match_default
  593. )
  594. {
  595. using namespace regex_constants;
  596. typedef detail::core_access<BidiIter> access;
  597. BOOST_ASSERT(0 != re.regex_id());
  598. BidiIter cur = begin;
  599. match_results<BidiIter> what;
  600. detail::match_state<BidiIter> state(begin, end, what, *access::get_regex_impl(re), flags);
  601. bool const yes_copy = (0 == (flags & format_no_copy));
  602. if(detail::regex_search_impl(state, re))
  603. {
  604. if(yes_copy)
  605. {
  606. out = std::copy(cur, what[0].first, out);
  607. }
  608. out = what.format(out, format, flags);
  609. cur = state.cur_ = state.next_search_ = what[0].second;
  610. if(0 == (flags & format_first_only))
  611. {
  612. bool not_null = (0 == what.length());
  613. state.reset(what, *access::get_regex_impl(re));
  614. while(detail::regex_search_impl(state, re, not_null))
  615. {
  616. if(yes_copy)
  617. {
  618. out = std::copy(cur, what[0].first, out);
  619. }
  620. access::set_prefix_suffix(what, begin, end);
  621. out = what.format(out, format, flags);
  622. cur = state.cur_ = state.next_search_ = what[0].second;
  623. not_null = (0 == what.length());
  624. state.reset(what, *access::get_regex_impl(re));
  625. }
  626. }
  627. }
  628. if(yes_copy)
  629. {
  630. out = std::copy(cur, end, out);
  631. }
  632. return out;
  633. }
  634. } // namespace detail
  635. /// \brief Build an output sequence given an input sequence, a regex, and a format string or
  636. /// a formatter object, function, or expression.
  637. ///
  638. /// Constructs a \c regex_iterator object: <tt>regex_iterator\< BidiIter \> i(begin, end, re, flags)</tt>,
  639. /// and uses \c i to enumerate through all of the matches m of type <tt>match_results\< BidiIter \></tt> that
  640. /// occur within the sequence <tt>[begin, end)</tt>. If no such matches are found and <tt>!(flags \& format_no_copy)</tt>
  641. /// then calls <tt>std::copy(begin, end, out)</tt>. Otherwise, for each match found, if <tt>!(flags \& format_no_copy)</tt>
  642. /// calls <tt>std::copy(m.prefix().first, m.prefix().second, out)</tt>, and then calls <tt>m.format(out, format, flags)</tt>.
  643. /// Finally if <tt>!(flags \& format_no_copy)</tt> calls <tt>std::copy(last_m.suffix().first, last_m.suffix().second, out)</tt>
  644. /// where \c last_m is a copy of the last match found.
  645. ///
  646. /// If <tt>flags \& format_first_only</tt> is non-zero then only the first match found is replaced.
  647. ///
  648. /// \pre Type \c BidiIter meets the requirements of a Bidirectional Iterator (24.1.4).
  649. /// \pre Type \c OutIter meets the requirements of an Output Iterator (24.1.2).
  650. /// \pre Type \c Formatter models \c ForwardRange, <tt>Callable\<match_results\<BidiIter\> \></tt>,
  651. /// <tt>Callable\<match_results\<BidiIter\>, OutIter\></tt>, or
  652. /// <tt>Callable\<match_results\<BidiIter\>, OutIter, regex_constants::match_flag_type\></tt>;
  653. /// or else it is a null-terminated format string, or an expression template
  654. /// representing a formatter lambda expression.
  655. /// \pre <tt>[begin,end)</tt> denotes a valid iterator range.
  656. /// \param out An output iterator into which the output sequence is written.
  657. /// \param begin The beginning of the input sequence.
  658. /// \param end The end of the input sequence.
  659. /// \param re The regular expression object to use.
  660. /// \param format The format string used to format the replacement sequence,
  661. /// or a formatter function, function object, or expression.
  662. /// \param flags Optional match flags, used to control how the expression is matched against
  663. /// the sequence. (See \c match_flag_type.)
  664. /// \return The value of the output iterator after the output sequence has been written to it.
  665. /// \throw regex_error on stack exhaustion or invalid format string.
  666. template<typename OutIter, typename BidiIter, typename Formatter>
  667. inline OutIter regex_replace
  668. (
  669. OutIter out
  670. , BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) begin
  671. , BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) end
  672. , basic_regex<BidiIter> const &re
  673. , Formatter const &format
  674. , regex_constants::match_flag_type flags = regex_constants::match_default
  675. , typename disable_if<detail::is_char_ptr<Formatter> >::type * = 0
  676. )
  677. {
  678. // Default-constructed regexes match nothing
  679. if(0 == re.regex_id())
  680. {
  681. if((0 == (flags & regex_constants::format_no_copy)))
  682. {
  683. out = std::copy(begin, end, out);
  684. }
  685. return out;
  686. }
  687. return detail::regex_replace_impl(out, begin, end, re, format, flags);
  688. }
  689. /// \overload
  690. ///
  691. template<typename OutIter, typename BidiIter>
  692. inline OutIter regex_replace
  693. (
  694. OutIter out
  695. , BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) begin
  696. , BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) end
  697. , basic_regex<BidiIter> const &re
  698. , typename iterator_value<BidiIter>::type const *format
  699. , regex_constants::match_flag_type flags = regex_constants::match_default
  700. )
  701. {
  702. // Default-constructed regexes match nothing
  703. if(0 == re.regex_id())
  704. {
  705. if((0 == (flags & regex_constants::format_no_copy)))
  706. {
  707. out = std::copy(begin, end, out);
  708. }
  709. return out;
  710. }
  711. return detail::regex_replace_impl(out, begin, end, re, format, flags);
  712. }
  713. /// \overload
  714. ///
  715. template<typename BidiContainer, typename BidiIter, typename Formatter>
  716. inline BidiContainer regex_replace
  717. (
  718. BidiContainer &str
  719. , basic_regex<BidiIter> const &re
  720. , Formatter const &format
  721. , regex_constants::match_flag_type flags = regex_constants::match_default
  722. , typename disable_if<mpl::or_<detail::is_char_ptr<BidiContainer>, detail::is_char_ptr<Formatter> > >::type * = 0
  723. )
  724. {
  725. BidiContainer result;
  726. // Note that the result iterator of the range must be convertible
  727. // to BidiIter here.
  728. BidiIter begin = boost::begin(str), end = boost::end(str);
  729. // Default-constructed regexes match nothing
  730. if(0 == re.regex_id())
  731. {
  732. if((0 == (flags & regex_constants::format_no_copy)))
  733. {
  734. std::copy(begin, end, std::back_inserter(result));
  735. }
  736. return result;
  737. }
  738. detail::regex_replace_impl(std::back_inserter(result), begin, end, re, format, flags);
  739. return result;
  740. }
  741. /// \overload
  742. ///
  743. template<typename BidiContainer, typename BidiIter, typename Formatter>
  744. inline BidiContainer regex_replace
  745. (
  746. BidiContainer const &str
  747. , basic_regex<BidiIter> const &re
  748. , Formatter const &format
  749. , regex_constants::match_flag_type flags = regex_constants::match_default
  750. , typename disable_if<mpl::or_<detail::is_char_ptr<BidiContainer>, detail::is_char_ptr<Formatter> > >::type * = 0
  751. )
  752. {
  753. BidiContainer result;
  754. // Note that the result iterator of the range must be convertible
  755. // to BidiIter here.
  756. BidiIter begin = boost::begin(str), end = boost::end(str);
  757. // Default-constructed regexes match nothing
  758. if(0 == re.regex_id())
  759. {
  760. if((0 == (flags & regex_constants::format_no_copy)))
  761. {
  762. std::copy(begin, end, std::back_inserter(result));
  763. }
  764. return result;
  765. }
  766. detail::regex_replace_impl(std::back_inserter(result), begin, end, re, format, flags);
  767. return result;
  768. }
  769. /// \overload
  770. ///
  771. template<typename Char, typename Formatter>
  772. inline std::basic_string<typename remove_const<Char>::type> regex_replace
  773. (
  774. BOOST_XPR_NONDEDUCED_TYPE_(Char) *str
  775. , basic_regex<Char *> const &re
  776. , Formatter const &format
  777. , regex_constants::match_flag_type flags = regex_constants::match_default
  778. , typename disable_if<detail::is_char_ptr<Formatter> >::type * = 0
  779. )
  780. {
  781. typedef typename remove_const<Char>::type char_type;
  782. std::basic_string<char_type> result;
  783. // Default-constructed regexes match nothing
  784. if(0 == re.regex_id())
  785. {
  786. if((0 == (flags & regex_constants::format_no_copy)))
  787. {
  788. result = str;
  789. }
  790. return result;
  791. }
  792. Char *end = str + std::char_traits<char_type>::length(str);
  793. detail::regex_replace_impl(std::back_inserter(result), str, end, re, format, flags);
  794. return result;
  795. }
  796. /// \overload
  797. ///
  798. template<typename BidiContainer, typename BidiIter>
  799. inline BidiContainer regex_replace
  800. (
  801. BidiContainer &str
  802. , basic_regex<BidiIter> const &re
  803. , typename iterator_value<BidiIter>::type const *format
  804. , regex_constants::match_flag_type flags = regex_constants::match_default
  805. , typename disable_if<detail::is_char_ptr<BidiContainer> >::type * = 0
  806. )
  807. {
  808. BidiContainer result;
  809. // Note that the result iterator of the range must be convertible
  810. // to BidiIter here.
  811. BidiIter begin = boost::begin(str), end = boost::end(str);
  812. // Default-constructed regexes match nothing
  813. if(0 == re.regex_id())
  814. {
  815. if((0 == (flags & regex_constants::format_no_copy)))
  816. {
  817. std::copy(begin, end, std::back_inserter(result));
  818. }
  819. return result;
  820. }
  821. detail::regex_replace_impl(std::back_inserter(result), begin, end, re, format, flags);
  822. return result;
  823. }
  824. /// \overload
  825. ///
  826. template<typename BidiContainer, typename BidiIter>
  827. inline BidiContainer regex_replace
  828. (
  829. BidiContainer const &str
  830. , basic_regex<BidiIter> const &re
  831. , typename iterator_value<BidiIter>::type const *format
  832. , regex_constants::match_flag_type flags = regex_constants::match_default
  833. , typename disable_if<detail::is_char_ptr<BidiContainer> >::type * = 0
  834. )
  835. {
  836. BidiContainer result;
  837. // Note that the result iterator of the range must be convertible
  838. // to BidiIter here.
  839. BidiIter begin = boost::begin(str), end = boost::end(str);
  840. // Default-constructed regexes match nothing
  841. if(0 == re.regex_id())
  842. {
  843. if((0 == (flags & regex_constants::format_no_copy)))
  844. {
  845. std::copy(begin, end, std::back_inserter(result));
  846. }
  847. return result;
  848. }
  849. detail::regex_replace_impl(std::back_inserter(result), begin, end, re, format, flags);
  850. return result;
  851. }
  852. /// \overload
  853. ///
  854. template<typename Char>
  855. inline std::basic_string<typename remove_const<Char>::type> regex_replace
  856. (
  857. BOOST_XPR_NONDEDUCED_TYPE_(Char) *str
  858. , basic_regex<Char *> const &re
  859. , typename add_const<Char>::type *format
  860. , regex_constants::match_flag_type flags = regex_constants::match_default
  861. )
  862. {
  863. typedef typename remove_const<Char>::type char_type;
  864. std::basic_string<char_type> result;
  865. // Default-constructed regexes match nothing
  866. if(0 == re.regex_id())
  867. {
  868. if((0 == (flags & regex_constants::format_no_copy)))
  869. {
  870. result = str;
  871. }
  872. return result;
  873. }
  874. Char *end = str + std::char_traits<char_type>::length(str);
  875. detail::regex_replace_impl(std::back_inserter(result), str, end, re, format, flags);
  876. return result;
  877. }
  878. }} // namespace boost::xpressive
  879. #endif