2222
2323#include < utility>
2424
25+ #if defined(HAVE_STD_REGEX)
26+ #include < regex>
27+ #endif
28+
29+ #if defined(HAVE_PCRE)
2530#ifdef _WIN32
2631#define PCRE_STATIC
2732#endif
2833#include < pcre.h>
34+ #endif
2935
36+ enum class Regex ::Engine : std::uint8_t
37+ {
38+ Unknown = 0 ,
39+ #if defined(HAVE_PCRE)
40+ Pcre = 1 ,
41+ #endif
42+ #if defined(HAVE_STD_REGEX)
43+ Std = 2
44+ #endif
45+ };
46+
47+ #if defined(HAVE_PCRE)
3048namespace {
3149 std::string pcreErrorCodeToString (const int pcreExecRet)
3250 {
@@ -249,6 +267,58 @@ namespace {
249267 return " " ;
250268 }
251269}
270+ #endif // HAVE_PCRE
271+
272+ #if defined(HAVE_STD_REGEX)
273+ namespace {
274+ class StdRegex : public Regex
275+ {
276+ public:
277+ explicit StdRegex (std::string pattern)
278+ : mPattern(std::move(pattern))
279+ {}
280+
281+ std::string compile ()
282+ {
283+ if (mCompiled )
284+ return " regular expression has already been compiled" ;
285+
286+ try {
287+ mRegex = std::regex (mPattern );
288+ } catch (const std::exception& e) {
289+ return e.what ();
290+ }
291+ mCompiled = true ;
292+ return " " ;
293+ }
294+
295+ std::string match (const std::string& str, const MatchFn& matchFn) const override
296+ {
297+ if (!mCompiled )
298+ return " regular expression has not been compiled yet" ;
299+
300+ auto I = std::sregex_iterator (str.cbegin (), str.cend (), mRegex );
301+ const auto E = std::sregex_iterator ();
302+ while (I != E)
303+ {
304+ const std::smatch& match = *I;
305+ matchFn (match.position (), match.position () + match.length ());
306+ ++I;
307+ }
308+ return " " ;
309+ }
310+
311+ Engine engine () const override {
312+ return Engine::Std;
313+ }
314+
315+ private:
316+ std::string mPattern ;
317+ std::regex mRegex ;
318+ bool mCompiled {};
319+ };
320+ }
321+ #endif // HAVE_STD_REGEX
252322
253323template <typename T>
254324static T* createAndCompileRegex (std::string pattern, std::string& err)
@@ -261,10 +331,21 @@ static T* createAndCompileRegex(std::string pattern, std::string& err)
261331std::shared_ptr<Regex> Regex::create (std::string pattern, Engine engine, std::string& err)
262332{
263333 Regex* regex = nullptr ;
264- if (engine == Engine::Pcre)
265- regex = createAndCompileRegex<PcreRegex>(std::move (pattern), err);
266- else {
267- err = " unknown regular expression engine" ;
334+ switch (engine)
335+ {
336+ #if defined(HAVE_PCRE)
337+ case Engine::Pcre:
338+ regex = createAndCompileRegex<PcreRegex>(std::move (pattern), err);
339+ break ;
340+ #endif
341+ #if defined(HAVE_STD_REGEX)
342+ case Engine::Std:
343+ regex = createAndCompileRegex<StdRegex>(std::move (pattern), err);
344+ break ;
345+ #endif
346+ default :
347+ err = " unknown regular expression engine" ;
348+ break ;
268349 }
269350 if (!err.empty ()) {
270351 delete regex;
@@ -273,4 +354,27 @@ std::shared_ptr<Regex> Regex::create(std::string pattern, Engine engine, std::st
273354 return std::shared_ptr<Regex>(regex);
274355}
275356
357+ bool Regex::stringToEngine (const char * engine, Regex::Engine& regexEngine)
358+ {
359+ #if defined(HAVE_PCRE)
360+ if (std::strcmp (engine, " pcre" ) == 0 ) {
361+ regexEngine = Regex::Engine::Pcre;
362+ return true ;
363+ }
364+ #endif
365+ #if defined(HAVE_STD_REGEX)
366+ if (std::strcmp (engine, " std" ) == 0 ) {
367+ regexEngine = Regex::Engine::Std;
368+ return true ;
369+ }
370+ #endif
371+ regexEngine = Regex::Engine::Unknown;
372+ return false ;
373+ }
374+
375+ Regex::Engine Regex::defaultEngine ()
376+ {
377+ return Regex::Engine::Pcre;
378+ }
379+
276380#endif // HAVE_RULES
0 commit comments