• 用C++模板实现正则表达式


    好几年前写的代码了,贴出来跟大家分享一下。

     

     嘿嘿,支持[A-Za-z0-9_]+@[A-Za-z0-9_]+.[A-Za-z0-9_]+(.[A-Za-z0-9_]+)*

    还有很多Bug,正在测试当中,但是贴出来的代码是完全可以通过的。呵呵!

    Template.h

    #ifndef __TEMPLATE_H__

    #define __TEMPLATE_H__

    #include <windows.h>

    #include <string>

     

    using namespace std;

     

    namespace regular_expressions

    {

           template<typename T>

           class default_instance

           {

           public:

                  static T& Instance()

                  {

                         if ( m_instance == NULL )

                         {

                               m_instance = new T;

                         }

     

                         return *m_instance;

                  }

     

           private:

                  static T* m_instance;

           };

     

           template<typename T> T* default_instance<T>::m_instance = NULL;

           class match_true

           {

           public:

                  template<typename T>

                  bool IsMatch(T& val, T val2)

                  {

                         return true;

                  }

     

                  int Advance()

                  {

                         return 0;

                  }

           };

     

           class match_false

           {

           public:

                  template<typename T>

                  bool IsMatch(T& val, T val2)

                  {

                         return false;

                  }

     

                  int Advance()

                  {

                         return 0;

                  }

           };

     

           template<typename T>

           int ChacatersNeedAdvance(T& composableClass)

           {

                  return composableClass.Advance();

           }

     

           template<typename T>

           int ChacatersNeedAdvance(T* composableClass)

           {

                  return composableClass->Advance();

           }

     

           template<>

           int ChacatersNeedAdvance<char>(char& composableClass)

           {

                  return 1;

           }

     

           template<>

           int ChacatersNeedAdvance<char>(char* composableClass)

           {

                  return 1;

           }

     

           template<typename It, typename M>

           bool DoMatch(It& iter, It& end, M& matcher)

           {

                  return matcher.IsMatch(iter, end);

           }

     

           template<>

           bool DoMatch<string::iterator, char>(string::iterator& iter, string::iterator& end, char& matcher)

           {

                  if ( iter == end )

                         return false;

     

                  bool ret = matcher == *iter;

                  if ( ret )

                  {

                         iter++;

                  }

     

                  return ret;

           }

     

           template<>

          bool DoMatch<string::const_iterator, char>(string::const_iterator& iter, string::const_iterator& end, char& matcher)

           {

                  if ( iter == end )

                         return false;

     

                  bool ret = matcher == *iter;

                  if ( ret )

                  {

                         iter++;

                  }

     

                  return ret;

           }

     

           template<>

           bool DoMatch<charchar>(char& iter, char& end, char& matcher)

           {

                  if ( iter == end )

                         return false;

     

                  bool ret = matcher == iter;

                  if ( ret )

                  {

                         iter++;

                  }

     

                  return ret;

           }

     

           template< >

           bool DoMatch<string::iterator, string>(string::iterator& iter, string::iterator& end, string& matcher)

           {

                  bool ret = true;

                  string::iterator& savedIter = iter;

                  string::const_iterator miter = matcher.begin();

     

                  for (; ((miter != matcher.end()) && (savedIter != end)); ++miter, ++savedIter)

                  {

                         ret = (*miter) == (*savedIter);

                  }

     

                  if ( (savedIter == end) && (miter != matcher.end()) )

                         ret = false;

     

                  if ( ret )

                  {

                         while ( iter != savedIter )

                               iter++;

                  }

     

                  return ret;

           }

     

           template< >

           bool DoMatch<string::const_iterator, string>(string::const_iterator& iter, string::const_iterator& end, string& matcher)

           {

                  bool ret = true;

                  string::const_iterator& savedIter = iter;

                  string::const_iterator miter = matcher.begin();

     

                  for (; ((miter != matcher.end()) && (savedIter != end)); ++miter, ++savedIter)

                  {

                         ret = (*miter) == (*savedIter);

                  }

     

                  if ( (savedIter == end) && (miter != matcher.end()) )

                         ret = false;

     

                  if ( ret )

                  {

                         while ( iter != savedIter )

                               iter++;

                  }

     

                  return ret;

     

           }

     

           template<typename T1,

                  typename T2 = T1,

                  typename T3 = T1,

                  typename T4 = T1>

           class any_characters

           {

           public:

                  any_characters(T1 val1,

                         T2 val2 = default_instance<T2>::Instance(),

                         T3 val3 = default_instance<T3>::Instance(),

                        T4 val4 = default_instance<T4>::Instance()) : m_val1(val1), m_val2(val2), m_val3(val3), m_val4(val4)

                  {

                  }

     

     

                  any_characters(const any_characters& other)

                         : m_val1(other.m_val1),

                         m_val2(other.m_val2),

                         m_val3(other.m_val3),

                         m_val4(other.m_val4)

                  {

                  }

     

           public:

     

                  template<typename It>

                  bool IsMatch(It& iter, It end)

                  {

                         if ( iter == end )

                               return false;

     

                         return DoMatch(iter, end, m_val1) ||

                               DoMatch(iter, end, m_val2) ||

                               DoMatch(iter, end, m_val3) ||

                               DoMatch(iter, end, m_val4);

                  }

     

                  int Advance()

                  {

                         int ret = 0;

                         int count = 0;

     

                         count = ChacatersNeedAdvance(m_val1);

                         if ( count > ret ) ret = count;

     

                         count = ChacatersNeedAdvance(m_val2);

                         if ( count > ret ) ret = count;

     

                         count = ChacatersNeedAdvance(m_val3);

                         if ( count > ret ) ret = count;

     

                         count = ChacatersNeedAdvance(m_val4);

                         if ( count > ret ) ret = count;

     

                         if ( ret == 0 )

                               ret = 1;

     

                         return ret;

                  }

     

                  template<typename It>

                  void AdvanceIterator(It& iter, It end)

                  {

                         int count = ChacatersNeedAdvance(this);

                         while ( --count >= 0 )

                         {

                               if ( iter == end )

                                      break;

     

                               iter++;

                         }

                  }

     

           private:

                  T1 m_val1;

                  T2 m_val2;

                  T3 m_val3;

                  T4 m_val4;

           };

     

           template<>

           class any_characters<char>

           {

           public:

                  any_characters(char val1,

                         char val2 = '/0',

                         char val3 = '/0',

                         char val4 = '/0') : m_val1(val1), m_val2(val2), m_val3(val3), m_val4(val4)

                  {

                  }

     

     

                  any_characters(const any_characters& other)

                         : m_val1(other.m_val1),

                         m_val2(other.m_val2),

                         m_val3(other.m_val3),

                         m_val4(other.m_val4)

                  {

                  }

     

           public:

                  template<typename It>

                  bool IsMatch(It& iter, It end)

                  {

                         if ( iter == end )

                               return false;

     

                         return m_val1 == *iter ||

                               m_val2 == *iter ||

                               m_val3 == *iter ||

                               m_val4 == *iter;

                  }

     

                  int Advance()

                  {

                         return 1;

                  }

     

                  template<typename It>

                  void AdvanceIterator(It& iter, It end)

                  {

                         int count = ChacatersNeedAdvance(this);

                         while ( --count >= 0 )

                         {

                               if ( iter == end )

                                      break;

     

                               iter++;

                         }

                  }

     

           private:

                  char m_val1;

                  char m_val2;

                  char m_val3;

                  char m_val4;

           };

     

           template<typename T1,

                  typename T2 = match_true,

                  typename T3 = match_true,

                  typename T4 = match_true>

           class all_characters

           {

           public:

                  all_characters(T1 val1,

                         T2 val2 = default_instance<T2>::Instance(),

                         T3 val3 = default_instance<T3>::Instance(),

                        T4 val4 = default_instance<T4>::Instance()) : m_val1(val1), m_val2(val2), m_val3(val3), m_val4(val4)

                  {

                  }

     

                  all_characters(const all_characters& other)

                         : m_val1(other.m_val1),

                         m_val2(other.m_val2),

                         m_val3(other.m_val3),

                         m_val4(other.m_val4)

                  {

                  }

     

           public:

                  template<typename It>

                  bool IsMatch(It& iter, It end)

                  {

                         if ( iter == end )

                               return false;

     

                         bool ret = true;

                         It savedIter = iter;

                         ret = ret && DoMatch(savedIter, end, m_val1);

                         ret = ret && DoMatch(savedIter, end, m_val2);

                         ret = ret && DoMatch(savedIter, end, m_val3);

                         ret = ret && DoMatch(savedIter, end, m_val4);

     

                         if ( ret )

                         {

                               while ( iter != savedIter )

                                      ++iter;

                         }

     

                         return ret;

                  }

     

                  int Advance()

                  {

                         int ret = 0;

                         int count = 0;

     

                         count = ChacatersNeedAdvance(m_val1);

                         ret += count;

                         count = ChacatersNeedAdvance(m_val2);

                         ret += count;

                         count = ChacatersNeedAdvance(m_val3);

                         ret += count;

                         count = ChacatersNeedAdvance(m_val4);

                         ret += count;

     

                         return ret;

                  }

     

                  template<typename It>

                  void AdvanceIterator(It& iter, It end)

                  {

                         PrivateAdvanceIteratorHelper(iter, end, this);

                  }

     

           private:

                  template<typename It, typename M>

                  void PrivateAdvanceIteratorHelper(It& iter, It end, M& matcher)

                  {

                         int count = ChacatersNeedAdvance(matcher);

                         while ( --count >= 0 )

                         {

                               if ( iter == end )

                                      break;

     

                               iter++;

                         }

                  }

     

           private:

                  T1 m_val1;

                  T2 m_val2;

                  T3 m_val3;

                  T4 m_val4;

           };

     

           template<typename T>

           class OpenRightEndRangeComparer

           {

           public:

                  OpenRightEndRangeComparer(T lowend, T highend) : m_lowend(lowend), m_highend(highend)

                  {

                  }

     

           public:

                  bool InRange(T val)

                  {

                         return (val - m_lowend > 0) && (m_highend - val >= 0);

                  }

     

           private:

                  T m_lowend;

                  T m_highend;

           };

     

           template<typename T>

           class CloseEndsRangeComparer

           {

           public:

                  CloseEndsRangeComparer(T lowend, T highend) : m_lowend(lowend), m_highend(highend)

                  {

                  }

     

           public:

                  bool InRange(T val)

                  {

                         return (val - m_lowend > 0) && (m_highend - val > 0);

                  }

     

           private:

                  T m_lowend;

                  T m_highend;

           };

     

           template<typename T>

           class OpenLeftEndRangeComparer

           {

           public:

                  OpenLeftEndRangeComparer(T lowend, T highend) : m_lowend(lowend), m_highend(highend)

                  {

                  }

     

           public:

                  bool InRange(T val)

                  {

                         return (val - m_lowend >= 0) && (m_highend - val > 0);

                  }

     

           private:

                  T m_lowend;

                  T m_highend;

           };

     

           template<typename T>

           class OpenEndsRangeComparer

           {

           public:

                  OpenEndsRangeComparer(T lowend, T highend) : m_lowend(lowend), m_highend(highend)

                  {

                  }

     

           public:

                  bool InRange(T val)

                  {

                         return (val - m_lowend >= 0) && (m_highend - val >= 0);

                  }

     

           private:

                  T m_lowend;

                  T m_highend;

           };

     

           template<typename T, typename C = OpenEndsRangeComparer<T> >

           class range

           {

           public:

                  range(T lowend, T highend) :

                    m_lowend(lowend),

                           m_highend(highend),

                           m_comparer(lowend, highend)

                    {

                    }

     

                    range(const range& other) : m_lowend(other.m_lowend),

                           m_highend(other.m_highend),

                           m_comparer(m_lowend, m_highend)

                    {

                    }

     

           public:

                  template<typename It>

                  bool IsMatch(It& iter, It end)

                  {

                         if ( iter == end )

                               return false;

                         else

                               return m_comparer.InRange(*iter);

                  }

     

                  int Advance()

                  {

                         return 0;

                  }

     

           private:

                  T m_lowend;

                  T m_highend;

                  C m_comparer;

           };

     

           // A*

     

           template<typename M>

           class aterisk_quantifier

           {

           public:

                  aterisk_quantifier(M matcher) : m_matcher(matcher)

                  {

                  }

     

                  aterisk_quantifier(const aterisk_quantifier& other) : m_matcher(other.m_matcher)

                  {

                  }

     

           public:

                  template<typename It>

                  bool IsMatch(It& iter, It end)

                  {

                         It& savedIter = iter;

                         while ( m_matcher.IsMatch(savedIter, end) )

                         {

                               ;

                         }

     

                         return true;

                  }

     

                  int Advance()

                  {

                         return 0;

                  }

     

                  template<typename It>

                  void AdvanceIterator(It& iter, It end)

                  {

                  }

     

           private:

                  M m_matcher;

           };

     

           // A+

           template<typename M>

           class plus_quantifier

           {

           public:

                  plus_quantifier(M matcher) : m_matcher(matcher)

                  {

                  }

     

                  plus_quantifier(const plus_quantifier& other) : m_matcher(other.m_matcher)

                  {

                  }

     

           public:

                  template<typename It>

                  bool IsMatch(It& iter, It end)

                  {

                         bool ret = true;

                         bool atleastonmatches = false;

                         do

                         {

                               It& savedIter = iter;

                               ret = ret && m_matcher.IsMatch(savedIter, end);

                               if ( ret )

                               {

                                      atleastonmatches = true;

                                      int count = ChacatersNeedAdvance(m_matcher);

     

                                      while ( --count >= 0 )

                                             iter++;

                               }

                         } while ( ret );

     

                         return atleastonmatches;

                  }

     

                  int Advance()

                  {

                         return 0;

                  }

     

                  template<typename It>

                  void AdvanceIterator(It& iter, It end)

                  {

                  }

     

           private:

                  M m_matcher;

           };

     

     

           // A?

           template<typename M>

           class question_mark_quantifier

           {

           public:

                  question_mark_quantifier(M matcher) : m_matcher(matcher)

                  {

                  }

     

                  question_mark_quantifier(const question_mark_quantifier& other) : m_matcher(other.m_matcher)

                  {

                  }

     

           public:

                  template<typename It>

                  bool IsMatch(It& iter, It end)

                  {

                         m_matcher.IsMatch(iter, end);

                         return true;

                  }

     

                  int Advance()

                  {

                         return 0;

                  }

     

                  template<typename It>

                  void AdvanceIterator(It& iter, It end)

                  {

                  }

     

           private:

                  M m_matcher;

           };

    }

    #endif

     

    MatchEmail.cpp

    // ParseStudy.cpp : Defines the entry point for the console application.

     

    //

     

    #include "stdafx.h"

    #include "Templates.h"

    #include <iostream>

     

    using namespace std;

    using namespace regular_expressions;

     

    typedef any_characters<range<char>, range<char>, range<char>, char> word_class;

    void MatchEmail(const string &email)

    {

           // regex: [A-za-z0-9_-]+@[A-za-z0-9_-]+.[[A-za-z0-9_-]+(.[A-za-z0-9_-]+)*

     

           range<char> upcases('A''Z');

           range<char> lowcases('a''z');

           range<char> digit('0''9');

           any_characters<charchar> temp('_''-');

     

           // [A-Za-z0-9_]

           word_class word(upcases, lowcases, digit, '_');

     

           // [A-Za-z0-9_-]+@[A-Za-z0-9_-]+.[A-Za-z0-9_-]+(.[A-Za-z0-9_-]+)*

           // [A-Za-z0-9_-]+

           plus_quantifier<word_class> wordplus(word);

           // .[A-Za-z0-9_-]+

           all_characters<char, plus_quantifier<word_class> > dotwordplus('.', wordplus);

           // (.[A-Za-z0-9_-]+)*

           aterisk_quantifier<all_characters<char, plus_quantifier<word_class> > > dotwordaterisk(dotwordplus);

           // (.[A-Za-z0-9_-]+)?

           question_mark_quantifier<all_characters<char, plus_quantifier<word_class> > > dotwordquestion(dotwordplus);

     

           all_characters<plus_quantifier<word_class>,

                  all_characters<char, plus_quantifier<word_class> >,

                  question_mark_quantifier<all_characters<char, plus_quantifier<word_class> > > > at_right(wordplus, dotwordplus, dotwordquestion);

           all_characters<plus_quantifier<word_class>,

                  char,

                  all_characters<plus_quantifier<word_class>,

                  all_characters<char, plus_quantifier<word_class> >,

                  question_mark_quantifier<all_characters<char, plus_quantifier<word_class> > > > > fmtEmail(wordplus, '@', at_right);

           bool matches = true;

     

           for ( string::const_iterator iter = email.begin(); iter != email.end(); )

           {

                  int count = ChacatersNeedAdvance(fmtEmail);

                  if ( (email.end() - iter) < count )

                  {

                         matches = false;

                         break;

                  }

     

                  matches = matches && fmtEmail.IsMatch(iter, email.end());

                  fmtEmail.AdvanceIterator(iter, email.end());

           }

     

           if ( matches )

           {

                  cout << "[MATCH]: " << email << endl;

           }

           else

           {

                  cout << "[UNMATCH]: " << email << endl;

           }

    }

     

    int _tmain(int argc, _TCHAR* argv[])

    {

           MatchEmail("abc");

           MatchEmail("b");

           MatchEmail("c");

           MatchEmail("A");

           MatchEmail("Z");

           MatchEmail("zzz");

           MatchEmail("9");

           MatchEmail("0");

           MatchEmail("10");

           MatchEmail("-");

           MatchEmail("_");

           MatchEmail("!");

           MatchEmail("@");

           MatchEmail("a@c.d");

           MatchEmail("ab@cd.dd");

           MatchEmail("yimin_shi@hotmail.com");

           MatchEmail("yimin_shi@hotmail.com.cn");

           MatchEmail("yimin_shi@hotmail.com.org.cn");

           MatchEmail("yimin_shi@hotmail.com.org.cn.cn.cn.cn.cn.cn");

           MatchEmail("yimin_shi.yimin_shi@hotmail.com");

     

           return 0;

    }  

  • 相关阅读:
    java基础——DecimalFormat
    剑指——重建二叉树
    error error: illegal character: 'u3000'
    Android: Unhandled exception java.net.malformedurlexception 异常笔记
    Android获取系统时间
    java基础——hashCode笔记
    golang 红黑树
    golang 实现跳表skiplist
    快排
    堆排序
  • 原文地址:https://www.cnblogs.com/killmyday/p/2545217.html
Copyright © 2020-2023  润新知