用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;

}  

posted @ 2012-06-11 16:13  donjuan  阅读(938)  评论(0编辑  收藏  举报