// file : cutl/re.hxx // copyright : Copyright (c) 2009-2017 Code Synthesis Tools CC // license : MIT; see accompanying LICENSE file #ifndef CUTL_RE_HXX #define CUTL_RE_HXX #include #include #include #include #include namespace cutl { namespace re { struct LIBCUTL_EXPORT format_base: exception { format_base (std::string const& d): description_ (d) {} ~format_base () LIBCUTL_NOTHROW_NOEXCEPT {} std::string const& description () const { return description_; } virtual char const* what () const LIBCUTL_NOTHROW_NOEXCEPT; protected: std::string description_; }; template struct basic_format: format_base { basic_format (std::basic_string const& e, std::string const& d) : format_base (d), regex_ (e) {} ~basic_format () LIBCUTL_NOTHROW_NOEXCEPT {} std::basic_string const& regex () const { return regex_; } private: std::basic_string regex_; }; typedef basic_format format; typedef basic_format wformat; // Regular expression pattern. // template struct basic_regex { typedef std::basic_string string_type; ~basic_regex (); basic_regex (): impl_ (0) {init (0, false);} explicit basic_regex (string_type const& s, bool icase = false) : impl_ (0) { init (&s, icase); } basic_regex& operator= (string_type const& s) { init (&s, false); return *this; } basic_regex& assign (string_type const& s, bool icase = false) { init (&s, icase); return *this; } basic_regex (basic_regex const&); basic_regex& operator= (basic_regex const&); public: bool match (string_type const&) const; bool search (string_type const&) const; string_type replace (string_type const& s, string_type const& sub, bool first_only = false) const; public: string_type const& str () const { return str_; } bool empty () const { return str_.empty (); } private: void init (string_type const*, bool); private: struct impl; string_type str_; // Text representation of regex. impl* impl_; }; template inline std::basic_ostream& operator<< (std::basic_ostream& os, basic_regex const& r) { return os << r.str (); } typedef basic_regex regex; typedef basic_regex wregex; // Regular expression pattern and substituation. // template struct basic_regexsub { typedef basic_regex regex_type; typedef std::basic_string string_type; basic_regexsub () {} // Expression is of the form /regex/substitution/ where '/' can // be replaced with any delimiter. Delimiters must be escaped in // regex and substitution using back slashes (e.g., "\/"). Back // slashes themselves can be escaped using the double back slash // sequence (e.g., "\\"). // explicit basic_regexsub (string_type const& e) {init (e);} basic_regexsub (string_type const& regex, string_type const& sub) : regex_ (regex), sub_ (sub) { } basic_regexsub (regex_type const& regex, string_type const& sub) : regex_ (regex), sub_ (sub) { } basic_regexsub& operator= (string_type const& e) { init (e); return *this; } public: bool match (string_type const& s) const { return regex_.match (s); } bool search (string_type const& s) const { return regex_.search (s); } string_type replace (string_type const& s, bool first_only = false) const { return regex_.replace (s, sub_, first_only); } public: const regex_type& regex () const { return regex_; } const string_type& substitution () const { return sub_; } bool empty () const { return sub_.empty () && regex_.empty (); } private: void init (string_type const&); private: regex_type regex_; string_type sub_; }; typedef basic_regexsub regexsub; typedef basic_regexsub wregexsub; // Once-off regex execution. // template inline bool match (std::basic_string const& s, std::basic_string const& regex) { basic_regex r (regex); return r.match (s); } template inline bool search (std::basic_string const& s, std::basic_string const& regex) { basic_regex r (regex); return r.search (s); } template inline std::basic_string replace (std::basic_string const& s, std::basic_string const& regex, std::basic_string const& sub, bool first_only = false) { basic_regex r (regex); return r.replace (s, sub, first_only); } template inline std::basic_string replace (std::basic_string const& s, std::basic_string const& regexsub, // /regex/subst/ bool first_only = false) { basic_regexsub r (regexsub); return r.replace (s, first_only); } // Utility function for parsing expressions in the form /regex/subst/ // where '/' can be replaced with any delimiter. This function handles // escaping. It return the position of the next delimiter and stores // the unescaped chunk in result or throws the format exception if // the expression is invalid. // template typename std::basic_string::size_type parse (std::basic_string const& s, typename std::basic_string::size_type start, std::basic_string& result); } } #include #endif // CUTL_RE_HXX