Chris@16: // Boost string_algo library regex.hpp header file ---------------------------// Chris@16: Chris@16: // Copyright Pavol Droba 2002-2003. Chris@16: // Chris@16: // Distributed under the Boost Software License, Version 1.0. Chris@16: // (See accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: // See http://www.boost.org/ for updates, documentation, and revision history. Chris@16: Chris@16: #ifndef BOOST_STRING_REGEX_HPP Chris@16: #define BOOST_STRING_REGEX_HPP Chris@16: Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: /*! \file Chris@16: Defines regex variants of the algorithms. Chris@16: */ Chris@16: Chris@16: namespace boost { Chris@16: namespace algorithm { Chris@16: Chris@16: // find_regex -----------------------------------------------// Chris@16: Chris@16: //! Find regex algorithm Chris@16: /*! Chris@16: Search for a substring matching the given regex in the input. Chris@16: Chris@16: \param Input A container which will be searched. Chris@16: \param Rx A regular expression Chris@16: \param Flags Regex options Chris@16: \return Chris@16: An \c iterator_range delimiting the match. Chris@16: Returned iterator is either \c RangeT::iterator or Chris@16: \c RangeT::const_iterator, depending on the constness of Chris@16: the input parameter. Chris@16: Chris@16: \note This function provides the strong exception-safety guarantee Chris@16: */ Chris@16: template< Chris@16: typename RangeT, Chris@16: typename CharT, Chris@16: typename RegexTraitsT> Chris@16: inline iterator_range< Chris@16: BOOST_STRING_TYPENAME range_iterator::type > Chris@16: find_regex( Chris@16: RangeT& Input, Chris@16: const basic_regex& Rx, Chris@16: match_flag_type Flags=match_default ) Chris@16: { Chris@16: iterator_range::type> lit_input(::boost::as_literal(Input)); Chris@16: Chris@16: return ::boost::algorithm::regex_finder(Rx,Flags)( Chris@16: ::boost::begin(lit_input), ::boost::end(lit_input) ); Chris@16: } Chris@16: Chris@16: // replace_regex --------------------------------------------------------------------// Chris@16: Chris@16: //! Replace regex algorithm Chris@16: /*! Chris@16: Search for a substring matching given regex and format it with Chris@16: the specified format. Chris@16: The result is a modified copy of the input. It is returned as a sequence Chris@16: or copied to the output iterator. Chris@16: Chris@16: \param Output An output iterator to which the result will be copied Chris@16: \param Input An input string Chris@16: \param Rx A regular expression Chris@16: \param Format Regex format definition Chris@16: \param Flags Regex options Chris@16: \return An output iterator pointing just after the last inserted character or Chris@16: a modified copy of the input Chris@16: Chris@16: \note The second variant of this function provides the strong exception-safety guarantee Chris@16: */ Chris@16: template< Chris@16: typename OutputIteratorT, Chris@16: typename RangeT, Chris@16: typename CharT, Chris@16: typename RegexTraitsT, Chris@16: typename FormatStringTraitsT, typename FormatStringAllocatorT > Chris@16: inline OutputIteratorT replace_regex_copy( Chris@16: OutputIteratorT Output, Chris@16: const RangeT& Input, Chris@16: const basic_regex& Rx, Chris@16: const std::basic_string& Format, Chris@16: match_flag_type Flags=match_default | format_default ) Chris@16: { Chris@16: return ::boost::algorithm::find_format_copy( Chris@16: Output, Chris@16: Input, Chris@16: ::boost::algorithm::regex_finder( Rx, Flags ), Chris@16: ::boost::algorithm::regex_formatter( Format, Flags ) ); Chris@16: } Chris@16: Chris@16: //! Replace regex algorithm Chris@16: /*! Chris@16: \overload Chris@16: */ Chris@16: template< Chris@16: typename SequenceT, Chris@16: typename CharT, Chris@16: typename RegexTraitsT, Chris@16: typename FormatStringTraitsT, typename FormatStringAllocatorT > Chris@16: inline SequenceT replace_regex_copy( Chris@16: const SequenceT& Input, Chris@16: const basic_regex& Rx, Chris@16: const std::basic_string& Format, Chris@16: match_flag_type Flags=match_default | format_default ) Chris@16: { Chris@16: return ::boost::algorithm::find_format_copy( Chris@16: Input, Chris@16: ::boost::algorithm::regex_finder( Rx, Flags ), Chris@16: ::boost::algorithm::regex_formatter( Format, Flags ) ); Chris@16: } Chris@16: Chris@16: //! Replace regex algorithm Chris@16: /*! Chris@16: Search for a substring matching given regex and format it with Chris@16: the specified format. The input string is modified in-place. Chris@16: Chris@16: \param Input An input string Chris@16: \param Rx A regular expression Chris@16: \param Format Regex format definition Chris@16: \param Flags Regex options Chris@16: */ Chris@16: template< Chris@16: typename SequenceT, Chris@16: typename CharT, Chris@16: typename RegexTraitsT, Chris@16: typename FormatStringTraitsT, typename FormatStringAllocatorT > Chris@16: inline void replace_regex( Chris@16: SequenceT& Input, Chris@16: const basic_regex& Rx, Chris@16: const std::basic_string& Format, Chris@16: match_flag_type Flags=match_default | format_default ) Chris@16: { Chris@16: ::boost::algorithm::find_format( Chris@16: Input, Chris@16: ::boost::algorithm::regex_finder( Rx, Flags ), Chris@16: ::boost::algorithm::regex_formatter( Format, Flags ) ); Chris@16: } Chris@16: Chris@16: // replace_all_regex --------------------------------------------------------------------// Chris@16: Chris@16: //! Replace all regex algorithm Chris@16: /*! Chris@16: Format all substrings, matching given regex, with the specified format. Chris@16: The result is a modified copy of the input. It is returned as a sequence Chris@16: or copied to the output iterator. Chris@16: Chris@16: \param Output An output iterator to which the result will be copied Chris@16: \param Input An input string Chris@16: \param Rx A regular expression Chris@16: \param Format Regex format definition Chris@16: \param Flags Regex options Chris@16: \return An output iterator pointing just after the last inserted character or Chris@16: a modified copy of the input Chris@16: Chris@16: \note The second variant of this function provides the strong exception-safety guarantee Chris@16: */ Chris@16: template< Chris@16: typename OutputIteratorT, Chris@16: typename RangeT, Chris@16: typename CharT, Chris@16: typename RegexTraitsT, Chris@16: typename FormatStringTraitsT, typename FormatStringAllocatorT > Chris@16: inline OutputIteratorT replace_all_regex_copy( Chris@16: OutputIteratorT Output, Chris@16: const RangeT& Input, Chris@16: const basic_regex& Rx, Chris@16: const std::basic_string& Format, Chris@16: match_flag_type Flags=match_default | format_default ) Chris@16: { Chris@16: return ::boost::algorithm::find_format_all_copy( Chris@16: Output, Chris@16: Input, Chris@16: ::boost::algorithm::regex_finder( Rx, Flags ), Chris@16: ::boost::algorithm::regex_formatter( Format, Flags ) ); Chris@16: } Chris@16: Chris@16: //! Replace all regex algorithm Chris@16: /*! Chris@16: \overload Chris@16: */ Chris@16: template< Chris@16: typename SequenceT, Chris@16: typename CharT, Chris@16: typename RegexTraitsT, Chris@16: typename FormatStringTraitsT, typename FormatStringAllocatorT > Chris@16: inline SequenceT replace_all_regex_copy( Chris@16: const SequenceT& Input, Chris@16: const basic_regex& Rx, Chris@16: const std::basic_string& Format, Chris@16: match_flag_type Flags=match_default | format_default ) Chris@16: { Chris@16: return ::boost::algorithm::find_format_all_copy( Chris@16: Input, Chris@16: ::boost::algorithm::regex_finder( Rx, Flags ), Chris@16: ::boost::algorithm::regex_formatter( Format, Flags ) ); Chris@16: } Chris@16: Chris@16: //! Replace all regex algorithm Chris@16: /*! Chris@16: Format all substrings, matching given regex, with the specified format. Chris@16: The input string is modified in-place. Chris@16: Chris@16: \param Input An input string Chris@16: \param Rx A regular expression Chris@16: \param Format Regex format definition Chris@16: \param Flags Regex options Chris@16: */ Chris@16: template< Chris@16: typename SequenceT, Chris@16: typename CharT, Chris@16: typename RegexTraitsT, Chris@16: typename FormatStringTraitsT, typename FormatStringAllocatorT > Chris@16: inline void replace_all_regex( Chris@16: SequenceT& Input, Chris@16: const basic_regex& Rx, Chris@16: const std::basic_string& Format, Chris@16: match_flag_type Flags=match_default | format_default ) Chris@16: { Chris@16: ::boost::algorithm::find_format_all( Chris@16: Input, Chris@16: ::boost::algorithm::regex_finder( Rx, Flags ), Chris@16: ::boost::algorithm::regex_formatter( Format, Flags ) ); Chris@16: } Chris@16: Chris@16: // erase_regex --------------------------------------------------------------------// Chris@16: Chris@16: //! Erase regex algorithm Chris@16: /*! Chris@16: Remove a substring matching given regex from the input. Chris@16: The result is a modified copy of the input. It is returned as a sequence Chris@16: or copied to the output iterator. Chris@16: Chris@16: \param Output An output iterator to which the result will be copied Chris@16: \param Input An input string Chris@16: \param Rx A regular expression Chris@16: \param Flags Regex options Chris@16: \return An output iterator pointing just after the last inserted character or Chris@16: a modified copy of the input Chris@16: Chris@16: \note The second variant of this function provides the strong exception-safety guarantee Chris@16: */ Chris@16: template< Chris@16: typename OutputIteratorT, Chris@16: typename RangeT, Chris@16: typename CharT, Chris@16: typename RegexTraitsT > Chris@16: inline OutputIteratorT erase_regex_copy( Chris@16: OutputIteratorT Output, Chris@16: const RangeT& Input, Chris@16: const basic_regex& Rx, Chris@16: match_flag_type Flags=match_default ) Chris@16: { Chris@16: return ::boost::algorithm::find_format_copy( Chris@16: Output, Chris@16: Input, Chris@16: ::boost::algorithm::regex_finder( Rx, Flags ), Chris@16: ::boost::algorithm::empty_formatter( Input ) ); Chris@16: } Chris@16: Chris@16: //! Erase regex algorithm Chris@16: /*! Chris@16: \overload Chris@16: */ Chris@16: template< Chris@16: typename SequenceT, Chris@16: typename CharT, Chris@16: typename RegexTraitsT > Chris@16: inline SequenceT erase_regex_copy( Chris@16: const SequenceT& Input, Chris@16: const basic_regex& Rx, Chris@16: match_flag_type Flags=match_default ) Chris@16: { Chris@16: return ::boost::algorithm::find_format_copy( Chris@16: Input, Chris@16: ::boost::algorithm::regex_finder( Rx, Flags ), Chris@16: ::boost::algorithm::empty_formatter( Input ) ); Chris@16: } Chris@16: Chris@16: //! Erase regex algorithm Chris@16: /*! Chris@16: Remove a substring matching given regex from the input. Chris@16: The input string is modified in-place. Chris@16: Chris@16: \param Input An input string Chris@16: \param Rx A regular expression Chris@16: \param Flags Regex options Chris@16: */ Chris@16: template< Chris@16: typename SequenceT, Chris@16: typename CharT, Chris@16: typename RegexTraitsT > Chris@16: inline void erase_regex( Chris@16: SequenceT& Input, Chris@16: const basic_regex& Rx, Chris@16: match_flag_type Flags=match_default ) Chris@16: { Chris@16: ::boost::algorithm::find_format( Chris@16: Input, Chris@16: ::boost::algorithm::regex_finder( Rx, Flags ), Chris@16: ::boost::algorithm::empty_formatter( Input ) ); Chris@16: } Chris@16: Chris@16: // erase_all_regex --------------------------------------------------------------------// Chris@16: Chris@16: //! Erase all regex algorithm Chris@16: /*! Chris@16: Erase all substrings, matching given regex, from the input. Chris@16: The result is a modified copy of the input. It is returned as a sequence Chris@16: or copied to the output iterator. Chris@16: Chris@16: Chris@16: \param Output An output iterator to which the result will be copied Chris@16: \param Input An input string Chris@16: \param Rx A regular expression Chris@16: \param Flags Regex options Chris@16: \return An output iterator pointing just after the last inserted character or Chris@16: a modified copy of the input Chris@16: Chris@16: \note The second variant of this function provides the strong exception-safety guarantee Chris@16: */ Chris@16: template< Chris@16: typename OutputIteratorT, Chris@16: typename RangeT, Chris@16: typename CharT, Chris@16: typename RegexTraitsT > Chris@16: inline OutputIteratorT erase_all_regex_copy( Chris@16: OutputIteratorT Output, Chris@16: const RangeT& Input, Chris@16: const basic_regex& Rx, Chris@16: match_flag_type Flags=match_default ) Chris@16: { Chris@16: return ::boost::algorithm::find_format_all_copy( Chris@16: Output, Chris@16: Input, Chris@16: ::boost::algorithm::regex_finder( Rx, Flags ), Chris@16: ::boost::algorithm::empty_formatter( Input ) ); Chris@16: } Chris@16: Chris@16: //! Erase all regex algorithm Chris@16: /*! Chris@16: \overload Chris@16: */ Chris@16: template< Chris@16: typename SequenceT, Chris@16: typename CharT, Chris@16: typename RegexTraitsT > Chris@16: inline SequenceT erase_all_regex_copy( Chris@16: const SequenceT& Input, Chris@16: const basic_regex& Rx, Chris@16: match_flag_type Flags=match_default ) Chris@16: { Chris@16: return ::boost::algorithm::find_format_all_copy( Chris@16: Input, Chris@16: ::boost::algorithm::regex_finder( Rx, Flags ), Chris@16: ::boost::algorithm::empty_formatter( Input ) ); Chris@16: } Chris@16: Chris@16: //! Erase all regex algorithm Chris@16: /*! Chris@16: Erase all substrings, matching given regex, from the input. Chris@16: The input string is modified in-place. Chris@16: Chris@16: \param Input An input string Chris@16: \param Rx A regular expression Chris@16: \param Flags Regex options Chris@16: */ Chris@16: template< Chris@16: typename SequenceT, Chris@16: typename CharT, Chris@16: typename RegexTraitsT> Chris@16: inline void erase_all_regex( Chris@16: SequenceT& Input, Chris@16: const basic_regex& Rx, Chris@16: match_flag_type Flags=match_default ) Chris@16: { Chris@16: ::boost::algorithm::find_format_all( Chris@16: Input, Chris@16: ::boost::algorithm::regex_finder( Rx, Flags ), Chris@16: ::boost::algorithm::empty_formatter( Input ) ); Chris@16: } Chris@16: Chris@16: // find_all_regex ------------------------------------------------------------------// Chris@16: Chris@16: //! Find all regex algorithm Chris@16: /*! Chris@16: This algorithm finds all substrings matching the give regex Chris@16: in the input. Chris@16: Chris@16: Each part is copied and added as a new element to the output container. Chris@16: Thus the result container must be able to hold copies Chris@16: of the matches (in a compatible structure like std::string) or Chris@16: a reference to it (e.g. using the iterator range class). Chris@16: Examples of such a container are \c std::vector Chris@16: or \c std::list> Chris@16: Chris@16: \param Result A container that can hold copies of references to the substrings. Chris@16: \param Input A container which will be searched. Chris@16: \param Rx A regular expression Chris@16: \param Flags Regex options Chris@16: \return A reference to the result Chris@16: Chris@16: \note Prior content of the result will be overwritten. Chris@16: Chris@16: \note This function provides the strong exception-safety guarantee Chris@16: */ Chris@16: template< Chris@16: typename SequenceSequenceT, Chris@16: typename RangeT, Chris@16: typename CharT, Chris@16: typename RegexTraitsT > Chris@16: inline SequenceSequenceT& find_all_regex( Chris@16: SequenceSequenceT& Result, Chris@16: const RangeT& Input, Chris@16: const basic_regex& Rx, Chris@16: match_flag_type Flags=match_default ) Chris@16: { Chris@16: return ::boost::algorithm::iter_find( Chris@16: Result, Chris@16: Input, Chris@16: ::boost::algorithm::regex_finder(Rx,Flags) ); Chris@16: } Chris@16: Chris@16: // split_regex ------------------------------------------------------------------// Chris@16: Chris@16: //! Split regex algorithm Chris@16: /*! Chris@16: Tokenize expression. This function is equivalent to C strtok. Input Chris@16: sequence is split into tokens, separated by separators. Separator Chris@16: is an every match of the given regex. Chris@16: Each part is copied and added as a new element to the output container. Chris@16: Thus the result container must be able to hold copies Chris@16: of the matches (in a compatible structure like std::string) or Chris@16: a reference to it (e.g. using the iterator range class). Chris@16: Examples of such a container are \c std::vector Chris@16: or \c std::list> Chris@16: Chris@16: \param Result A container that can hold copies of references to the substrings. Chris@16: \param Input A container which will be searched. Chris@16: \param Rx A regular expression Chris@16: \param Flags Regex options Chris@16: \return A reference to the result Chris@16: Chris@16: \note Prior content of the result will be overwritten. Chris@16: Chris@16: \note This function provides the strong exception-safety guarantee Chris@16: */ Chris@16: template< Chris@16: typename SequenceSequenceT, Chris@16: typename RangeT, Chris@16: typename CharT, Chris@16: typename RegexTraitsT > Chris@16: inline SequenceSequenceT& split_regex( Chris@16: SequenceSequenceT& Result, Chris@16: const RangeT& Input, Chris@16: const basic_regex& Rx, Chris@16: match_flag_type Flags=match_default ) Chris@16: { Chris@16: return ::boost::algorithm::iter_split( Chris@16: Result, Chris@16: Input, Chris@16: ::boost::algorithm::regex_finder(Rx,Flags) ); Chris@16: } Chris@16: Chris@16: // join_if ------------------------------------------------------------------// Chris@16: Chris@16: #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING Chris@16: Chris@16: //! Conditional join algorithm Chris@16: /*! Chris@16: This algorithm joins all strings in a 'list' into one long string. Chris@16: Segments are concatenated by given separator. Only segments that Chris@16: match the given regular expression will be added to the result Chris@16: Chris@16: This is a specialization of join_if algorithm. Chris@16: Chris@16: \param Input A container that holds the input strings. It must be a container-of-containers. Chris@16: \param Separator A string that will separate the joined segments. Chris@16: \param Rx A regular expression Chris@16: \param Flags Regex options Chris@16: \return Concatenated string. Chris@16: Chris@16: \note This function provides the strong exception-safety guarantee Chris@16: */ Chris@16: template< Chris@16: typename SequenceSequenceT, Chris@16: typename Range1T, Chris@16: typename CharT, Chris@16: typename RegexTraitsT > Chris@16: inline typename range_value::type Chris@16: join_if( Chris@16: const SequenceSequenceT& Input, Chris@16: const Range1T& Separator, Chris@16: const basic_regex& Rx, Chris@16: match_flag_type Flags=match_default ) Chris@16: { Chris@16: // Define working types Chris@16: typedef typename range_value::type ResultT; Chris@16: typedef typename range_const_iterator::type InputIteratorT; Chris@16: Chris@16: // Parse input Chris@16: InputIteratorT itBegin=::boost::begin(Input); Chris@16: InputIteratorT itEnd=::boost::end(Input); Chris@16: Chris@16: // Construct container to hold the result Chris@16: ResultT Result; Chris@16: Chris@16: Chris@16: // Roll to the first element that will be added Chris@16: while( Chris@16: itBegin!=itEnd && Chris@16: !::boost::regex_match(::boost::begin(*itBegin), ::boost::end(*itBegin), Rx, Flags)) ++itBegin; Chris@16: Chris@16: // Add this element Chris@16: if(itBegin!=itEnd) Chris@16: { Chris@16: detail::insert(Result, ::boost::end(Result), *itBegin); Chris@16: ++itBegin; Chris@16: } Chris@16: Chris@16: for(;itBegin!=itEnd; ++itBegin) Chris@16: { Chris@16: if(::boost::regex_match(::boost::begin(*itBegin), ::boost::end(*itBegin), Rx, Flags)) Chris@16: { Chris@16: // Add separator Chris@16: detail::insert(Result, ::boost::end(Result), ::boost::as_literal(Separator)); Chris@16: // Add element Chris@16: detail::insert(Result, ::boost::end(Result), *itBegin); Chris@16: } Chris@16: } Chris@16: Chris@16: return Result; Chris@16: } Chris@16: Chris@16: #else // BOOST_NO_FUNCTION_TEMPLATE_ORDERING Chris@16: Chris@16: //! Conditional join algorithm Chris@16: /*! Chris@16: This algorithm joins all strings in a 'list' into one long string. Chris@16: Segments are concatenated by given separator. Only segments that Chris@16: match the given regular expression will be added to the result Chris@16: Chris@16: This is a specialization of join_if algorithm. Chris@16: Chris@16: \param Input A container that holds the input strings. It must be a container-of-containers. Chris@16: \param Separator A string that will separate the joined segments. Chris@16: \param Rx A regular expression Chris@16: \param Flags Regex options Chris@16: \return Concatenated string. Chris@16: Chris@16: \note This function provides the strong exception-safety guarantee Chris@16: */ Chris@16: template< Chris@16: typename SequenceSequenceT, Chris@16: typename Range1T, Chris@16: typename CharT, Chris@16: typename RegexTraitsT > Chris@16: inline typename range_value::type Chris@16: join_if_regex( Chris@16: const SequenceSequenceT& Input, Chris@16: const Range1T& Separator, Chris@16: const basic_regex& Rx, Chris@16: match_flag_type Flags=match_default ) Chris@16: { Chris@16: // Define working types Chris@16: typedef typename range_value::type ResultT; Chris@16: typedef typename range_const_iterator::type InputIteratorT; Chris@16: Chris@16: // Parse input Chris@16: InputIteratorT itBegin=::boost::begin(Input); Chris@16: InputIteratorT itEnd=::boost::end(Input); Chris@16: Chris@16: // Construct container to hold the result Chris@16: ResultT Result; Chris@16: Chris@16: Chris@16: // Roll to the first element that will be added Chris@16: while( Chris@16: itBegin!=itEnd && Chris@16: !::boost::regex_match(::boost::begin(*itBegin), ::boost::end(*itBegin), Rx, Flags)) ++itBegin; Chris@16: Chris@16: // Add this element Chris@16: if(itBegin!=itEnd) Chris@16: { Chris@16: detail::insert(Result, ::boost::end(Result), *itBegin); Chris@16: ++itBegin; Chris@16: } Chris@16: Chris@16: for(;itBegin!=itEnd; ++itBegin) Chris@16: { Chris@16: if(::boost::regex_match(::boost::begin(*itBegin), ::boost::end(*itBegin), Rx, Flags)) Chris@16: { Chris@16: // Add separator Chris@16: detail::insert(Result, ::boost::end(Result), ::boost::as_literal(Separator)); Chris@16: // Add element Chris@16: detail::insert(Result, ::boost::end(Result), *itBegin); Chris@16: } Chris@16: } Chris@16: Chris@16: return Result; Chris@16: } Chris@16: Chris@16: Chris@16: #endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING Chris@16: Chris@16: } // namespace algorithm Chris@16: Chris@16: // pull names into the boost namespace Chris@16: using algorithm::find_regex; Chris@16: using algorithm::replace_regex; Chris@16: using algorithm::replace_regex_copy; Chris@16: using algorithm::replace_all_regex; Chris@16: using algorithm::replace_all_regex_copy; Chris@16: using algorithm::erase_regex; Chris@16: using algorithm::erase_regex_copy; Chris@16: using algorithm::erase_all_regex; Chris@16: using algorithm::erase_all_regex_copy; Chris@16: using algorithm::find_all_regex; Chris@16: using algorithm::split_regex; Chris@16: Chris@16: #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING Chris@16: using algorithm::join_if; Chris@16: #else // BOOST_NO_FUNCTION_TEMPLATE_ORDERING Chris@16: using algorithm::join_if_regex; Chris@16: #endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING Chris@16: Chris@16: } // namespace boost Chris@16: Chris@16: Chris@16: #endif // BOOST_STRING_REGEX_HPP