From 9486162f45178a6683f8cd7674ecb666ff6c194b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20W=C3=A4ckerlin?= Date: Tue, 14 Dec 2004 20:20:30 +0000 Subject: [PATCH] initial version --- mrw/regexp.cpp | 36 ++++++++++++++ mrw/regexp.hpp | 112 ++++++++++++++++++++++++++++++++++++++++++++ mrw/regexp_test.cpp | 45 ++++++++++++++++++ 3 files changed, 193 insertions(+) create mode 100644 mrw/regexp.cpp create mode 100644 mrw/regexp.hpp create mode 100644 mrw/regexp_test.cpp diff --git a/mrw/regexp.cpp b/mrw/regexp.cpp new file mode 100644 index 0000000..3d882c0 --- /dev/null +++ b/mrw/regexp.cpp @@ -0,0 +1,36 @@ +/** @file + + $Id$ + + $Date$ + $Author$ + + @copy © Marc Wäckerlin + @license LGPL, see file COPYING + + $Log$ + Revision 1.1 2004/12/14 20:20:30 marc + initial version + + +*/ + +#include +#include + +namespace mrw { + + RegExp::RegExp(const std::string& pattern, int flags) + throw(std::exception, std::bad_exception) { + if (regcomp(&_regex, pattern.c_str(), flags|nosub)) + throw(mrw::invalid_argument(pattern)); + } + + RegExp::~RegExp() throw() { + regfree(&_regex); + } + + bool RegExp::operator()(const std::string& text) const throw() { + return !regexec(const_cast(&_regex), text.c_str(), 0, 0, 0); + } +} diff --git a/mrw/regexp.hpp b/mrw/regexp.hpp new file mode 100644 index 0000000..22b79b5 --- /dev/null +++ b/mrw/regexp.hpp @@ -0,0 +1,112 @@ +/** @file + + $Id$ + + $Date$ + $Author$ + + @copy © Marc Wäckerlin + @license LGPL, see file COPYING + + $Log$ + Revision 1.1 2004/12/14 20:20:30 marc + initial version + + +*/ + +#include +#include +#include + +namespace mrw { + + /** @defgroup regexp Regular Expressions + + A simple wrapper around the C POSIX regular expression library + with a C++ Interface. + + Usage sample: + @code + std::ifstream file(filename); // read from a file + mrw::RegExp findBrackets("^\\[.*\\]$"); // look for "[some text]" + for (std::string line; + mrw::getline(file, line);) // read line by line + if (findBrackets(line)) // check for regular expression + found(line); // found, do something + @endcode + + */ + + /** @brief a regular expression + + This class manages a simple regular expression. + + Usage sample: + @code + std::ifstream file(filename); // read from a file + mrw::RegExp findBrackets("^\\[.*\\]$"); // look for "[some text]" + for (std::string line; + mrw::getline(file, line);) // read line by line + if (findBrackets(line)) // check for regular expression + found(line); // found, do something + @endcode + + */ + class RegExp { + + public: + + /** @brief flags that influence regular expressions + + Flag @c newline treats a newline in the text to be compared as + dividing the text into multiple lines, so that @c $ can match + before the newline and @c ^ can match after. Also, don't + permit @c . to match a newline, and don't permit @c [^...] to + match a newline. + + Otherwise, newline acts like any other ordinary character. + + Flag @c nosub is used internally, don't specify it. + + */ + enum Flags { + extended = REG_EXTENDED, ///< use extended regular expressions + icase = REG_ICASE, ///< ignore case in match + nosub = REG_NOSUB, ///< @b internal (report only success/fail) + newline = REG_NEWLINE ///< treat lines individually + }; + + /** @brief define a new regular expression + + The regular expression is compiled on instanciation and can + then be matced several times on different texts. + + @param pattern the regular expression pattern, thee the @c man + page for POSIX regular expressions (on linux: @c + info 7 regex) + @param flags special flags, they default to extended|nosub and + should consist of the Flag values combined with @c | + + @throw std::invalid_argument if pattern compilation fails + */ + RegExp(const std::string& pattern, int flags = extended) + throw(std::exception, std::bad_exception); + + /** @brief cleans up expression from memory */ + ~RegExp() throw(); + + /** @brief apply the expression, match a text against the expression + + @param text a text that is matched against the regular expression + @return + - true if @c text matches + - false otherwise */ + bool operator()(const std::string& text) const throw(); + + private: + + regex_t _regex; + + }; +} diff --git a/mrw/regexp_test.cpp b/mrw/regexp_test.cpp new file mode 100644 index 0000000..4b027ea --- /dev/null +++ b/mrw/regexp_test.cpp @@ -0,0 +1,45 @@ +/** @file + + $Id$ + + $Date$ + $Author$ + + @copy © Marc Wäckerlin + @license LGPL, see file COPYING + + $Log$ + Revision 1.1 2004/12/14 20:20:30 marc + initial version + + +*/ + +#include + +#include +#include +#include +#include + +class RegExpTest: public CppUnit::TestFixture { +public: + void CheckRegExp() { + mrw::RegExp findHalloWelt("^Hallo.*Welt$"); + CPPUNIT_ASSERT(findHalloWelt("Hallo Meine Welt")); + CPPUNIT_ASSERT(!findHalloWelt("xxx")); + CPPUNIT_ASSERT(!findHalloWelt("")); + CPPUNIT_ASSERT(!findHalloWelt(" Hallo Welt ")); + CPPUNIT_ASSERT(findHalloWelt("HalloWelt")); + } + CPPUNIT_TEST_SUITE(RegExpTest); + CPPUNIT_TEST(CheckRegExp); + CPPUNIT_TEST_SUITE_END(); +}; +CPPUNIT_TEST_SUITE_REGISTRATION(RegExpTest); + +int main() { + CppUnit::TextUi::TestRunner runner; + runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest()); + return runner.run() ? 0 : 1; +}