2020
2121#include " regex.h"
2222
23+ #include < regex>
2324#include < utility>
2425
2526#ifdef _WIN32
@@ -188,7 +189,7 @@ namespace {
188189 std::string PcreRegex::compile ()
189190 {
190191 if (mRe )
191- return " pcre_compile failed: regular expression has already been compiled" ;
192+ return " regular expression has already been compiled" ;
192193
193194 const char *pcreCompileErrorStr = nullptr ;
194195 int erroffset = 0 ;
@@ -222,7 +223,7 @@ namespace {
222223 std::string PcreRegex::match (const std::string& str, const MatchFn& match) const
223224 {
224225 if (!mRe )
225- return " pcre_exec failed: regular expression has not been compiled yet" ;
226+ return " regular expression has not been compiled yet" ;
226227
227228 int pos = 0 ;
228229 int ovector[30 ]= {0 };
@@ -246,10 +247,69 @@ namespace {
246247 }
247248}
248249
249- std::shared_ptr<Regex> Regex::create (std::string pattern, std::string& err)
250+ namespace {
251+ class StdRegex : public Regex
252+ {
253+ public:
254+ explicit StdRegex (std::string pattern)
255+ : mPattern(std::move(pattern))
256+ {}
257+
258+ std::string compile ()
259+ {
260+ if (mCompiled )
261+ return " regular expression has already been compiled" ;
262+
263+ try {
264+ mRegex = std::regex (mPattern );
265+ } catch (const std::exception& e) {
266+ return e.what ();
267+ }
268+ mCompiled = true ;
269+ return " " ;
270+ }
271+
272+ std::string match (const std::string& str, const MatchFn& matchFn) const override
273+ {
274+ if (!mCompiled )
275+ return " regular expression has not been compiled yet" ;
276+
277+ auto I = std::sregex_iterator (str.cbegin (), str.cend (), mRegex );
278+ const auto E = std::sregex_iterator ();
279+ while (I != E)
280+ {
281+ const std::smatch& match = *I;
282+ matchFn (match.position (), match.position () + match.length ());
283+ ++I;
284+ }
285+ return " " ;
286+ }
287+
288+ private:
289+ std::string mPattern ;
290+ std::regex mRegex ;
291+ bool mCompiled {};
292+ };
293+ }
294+
295+ template <typename T>
296+ static T* createAndCompileRegex (std::string pattern, std::string& err)
250297{
251- auto * regex = new PcreRegex (std::move (pattern));
298+ T * regex = new T (std::move (pattern));
252299 err = regex->compile ();
300+ return regex;
301+ }
302+
303+ std::shared_ptr<Regex> Regex::create (std::string pattern, Type type, std::string& err)
304+ {
305+ Regex* regex = nullptr ;
306+ if (type == Type::Pcre)
307+ regex = createAndCompileRegex<PcreRegex>(std::move (pattern), err);
308+ else if (type == Type::Std)
309+ regex = createAndCompileRegex<StdRegex>(std::move (pattern), err);
310+ else {
311+ err = " unknown regular expression type" ;
312+ }
253313 if (!err.empty ()) {
254314 delete regex;
255315 return nullptr ;
0 commit comments