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+ #if defined(HAVE_PCRE)
3037namespace {
3138 std::string pcreErrorCodeToString (const int pcreExecRet)
3239 {
@@ -249,6 +256,58 @@ namespace {
249256 return " " ;
250257 }
251258}
259+ #endif // HAVE_PCRE
260+
261+ #if defined(HAVE_STD_REGEX)
262+ namespace {
263+ class StdRegex : public Regex
264+ {
265+ public:
266+ explicit StdRegex (std::string pattern)
267+ : mPattern(std::move(pattern))
268+ {}
269+
270+ std::string compile ()
271+ {
272+ if (mCompiled )
273+ return " regular expression has already been compiled" ;
274+
275+ try {
276+ mRegex = std::regex (mPattern );
277+ } catch (const std::exception& e) {
278+ return e.what ();
279+ }
280+ mCompiled = true ;
281+ return " " ;
282+ }
283+
284+ std::string match (const std::string& str, const MatchFn& matchFn) const override
285+ {
286+ if (!mCompiled )
287+ return " regular expression has not been compiled yet" ;
288+
289+ auto I = std::sregex_iterator (str.cbegin (), str.cend (), mRegex );
290+ const auto E = std::sregex_iterator ();
291+ while (I != E)
292+ {
293+ const std::smatch& match = *I;
294+ matchFn (match.position (), match.position () + match.length ());
295+ ++I;
296+ }
297+ return " " ;
298+ }
299+
300+ Engine engine () const override {
301+ return Engine::Std;
302+ }
303+
304+ private:
305+ std::string mPattern ;
306+ std::regex mRegex ;
307+ bool mCompiled {};
308+ };
309+ }
310+ #endif // HAVE_STD_REGEX
252311
253312template <typename T>
254313static T* createAndCompileRegex (std::string pattern, std::string& err)
@@ -261,10 +320,21 @@ static T* createAndCompileRegex(std::string pattern, std::string& err)
261320std::shared_ptr<Regex> Regex::create (std::string pattern, Engine engine, std::string& err)
262321{
263322 Regex* regex = nullptr ;
264- if (engine == Engine::Pcre)
265- regex = createAndCompileRegex<PcreRegex>(std::move (pattern), err);
266- else {
267- err = " unknown regular expression engine" ;
323+ switch (engine)
324+ {
325+ #if defined(HAVE_PCRE)
326+ case Engine::Pcre:
327+ regex = createAndCompileRegex<PcreRegex>(std::move (pattern), err);
328+ break ;
329+ #endif
330+ #if defined(HAVE_STD_REGEX)
331+ case Engine::Std:
332+ regex = createAndCompileRegex<StdRegex>(std::move (pattern), err);
333+ break ;
334+ #endif
335+ default :
336+ err = " unknown regular expression engine" ;
337+ break ;
268338 }
269339 if (!err.empty ()) {
270340 delete regex;
@@ -273,4 +343,31 @@ std::shared_ptr<Regex> Regex::create(std::string pattern, Engine engine, std::st
273343 return std::shared_ptr<Regex>(regex);
274344}
275345
346+ bool Regex::stringToEngine (const char * engine, Regex::Engine& regexEngine)
347+ {
348+ #if defined(HAVE_PCRE)
349+ if (std::strcmp (engine, " pcre" ) == 0 ) {
350+ regexEngine = Regex::Engine::Pcre;
351+ return true ;
352+ }
353+ #endif
354+ #if defined(HAVE_STD_REGEX)
355+ if (std::strcmp (engine, " std" ) == 0 ) {
356+ regexEngine = Regex::Engine::Std;
357+ return true ;
358+ }
359+ #endif
360+ regexEngine = Regex::Engine::Unknown;
361+ return false ;
362+ }
363+
364+ Regex::Engine Regex::defaultEngine ()
365+ {
366+ #if defined(HAVE_PCRE)
367+ return Regex::Engine::Pcre;
368+ #else
369+ return Regex::Engine::Std;
370+ #endif
371+ }
372+
276373#endif // HAVE_RULES
0 commit comments