From da17cddd8fe5ab873de06eede24a6faa13e5eab9 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Tue, 5 Jul 2011 18:08:01 +0200 Subject: Actual regex implementation --- cutl/re.hxx | 245 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 245 insertions(+) create mode 100644 cutl/re.hxx (limited to 'cutl/re.hxx') diff --git a/cutl/re.hxx b/cutl/re.hxx new file mode 100644 index 0000000..57fa258 --- /dev/null +++ b/cutl/re.hxx @@ -0,0 +1,245 @@ +// file : cutl/re.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC +// license : MIT; see accompanying LICENSE file + +#ifndef CUTL_RE_HXX +#define CUTL_RE_HXX + +#include +#include // std::ostream + +#include +#include + +namespace cutl +{ + namespace re + { + struct LIBCUTL_EXPORT format: exception + { + virtual + ~format () throw (); + + format (std::string const& e, std::string const& d) + : regex_ (e), description_ (d) + { + } + + std::string const& + regex () const + { + return regex_; + } + + std::string const& + description () const + { + return description_; + } + + virtual char const* + what () const throw (); + + private: + std::string regex_; + std::string description_; + }; + + // Regular expression pattern. + // + struct LIBCUTL_EXPORT regex + { + ~regex (); + + regex () + : impl_ (0) + { + init (0); + } + + explicit + regex (std::string const& s) + : impl_ (0) + { + init (&s); + } + + regex& + operator= (std::string const& s) + { + init (&s); + return *this; + } + + regex (regex const&); + + regex& + operator= (regex const&); + + public: + bool + match (std::string const&) const; + + bool + search (std::string const&) const; + + std::string + replace (std::string const& s, + std::string const& sub, + bool first_only = false) const; + + public: + std::string + str () const; + + bool + empty () const; + + private: + void + init (std::string const*); + + private: + struct impl; + impl* impl_; + }; + + LIBCUTL_EXPORT std::ostream& + operator<< (std::ostream&, regex const&); + + // Regular expression pattern and substituation. + // + struct LIBCUTL_EXPORT regexsub + { + typedef re::regex regex_type; + + 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 + regexsub (std::string const& e) + { + init (e); + } + + regexsub (std::string const& regex, std::string const& sub) + : regex_ (regex), sub_ (sub) + { + } + + regexsub (regex_type const& regex, std::string const& sub) + : regex_ (regex), sub_ (sub) + { + } + + regexsub& + operator= (std::string const& e) + { + init (e); + return *this; + } + + public: + bool + match (std::string const& s) const + { + return regex_.match (s); + } + + bool + search (std::string const& s) const + { + return regex_.search (s); + } + + std::string + replace (std::string const& s, bool first_only = false) const + { + return regex_.replace (s, sub_, first_only); + } + + public: + const regex_type& + regex () const + { + return regex_; + } + + const std::string& + substitution () const + { + return sub_; + } + + bool + empty () const + { + return sub_.empty () && regex_.empty (); + } + + private: + void + init (std::string const&); + + private: + regex_type regex_; + std::string sub_; + }; + + // Once-off regex execution. + // + inline bool + match (std::string const& s, std::string const& regex) + { + re::regex r (regex); + return r.match (s); + } + + inline bool + search (std::string const& s, std::string const& regex) + { + re::regex r (regex); + return r.search (s); + } + + inline std::string + replace (std::string const& s, + std::string const& regex, + std::string const& sub, + bool first_only = false) + { + re::regex r (regex); + return r.replace (s, sub, first_only); + } + + inline std::string + replace (std::string const& s, + std::string const& regexsub, // /regex/subst/ + bool first_only = false) + { + re::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. + // + LIBCUTL_EXPORT std::string::size_type + parse (std::string const& s, + std::string::size_type start, + std::string& result); + } +} + +#endif // CUTL_RE_HXX -- cgit v1.1