#include "stdafx.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
/* 正则表达式的最大长度 */
#define MAX_REGSTR_LEN 256
char* match(char* reg,char* input);
char* twMatch(char * reg,char* input );
bool getSmallBracketString(char* subReg,char* reg)
{
int m = 1;
int nBracket = 1;
if (reg[0] != '(')
return false;
while(m < (int)strlen(reg))
{
if (reg[m] == '(')
nBracket++;
if (reg[m] == ')')
{
nBracket--;
if (nBracket == 0)
break;
}
m++;
}
if (m == (int)strlen(reg))
return false;
strncpy(subReg, reg+1, m-1);
return true;
}
bool findAt(char* addr,int counts,char ch)
{
int n;
for (n=0; n<counts; n++)
{
if (ch == addr[n])
return true;
}
return false;
}
/************************************************************************/
/* 处理后缀运算{ } API */
/************************************************************************/
char* matchBigBracket(char* reg, char* input)
{
int n;
int m = 0;
char scount[32] = {'\0'};
char subReg[MAX_REGSTR_LEN] = {'\0'};
while(m < (int)strlen(reg))
{
if (reg[m] == '{')
n = m;
if (reg[m] == '}')
break;
m++;
}
if ((m == (int)strlen(reg)) || m<=n)
return NULL;
strncpy(scount, reg+n+1, m-n-1);
int count = atoi(scount);
if (count == 0)
return match(reg+m+1, input);
else if(count <0)
return NULL;
strncpy(subReg, reg, n);
char *nextInput = match(subReg, input);
if (nextInput == NULL)
return NULL;/*如果没匹配成功进行()后面的匹配*/
else
{
count--;
char newReg[MAX_REGSTR_LEN] = {'\0'};
strncpy(newReg, reg, n+1);
sprintf(newReg+n+1, "%d", count);
strcat(newReg, reg+m);
return match(newReg, nextInput);
}
}
/************************************************************************/
/* 处理后缀运算* + ? API */
/************************************************************************/
char *matchOperate(char* reg,char* input,char* rSubReg,char *nextInput)
{
if (rSubReg[0] =='*')
{
if (nextInput == NULL)
return match(rSubReg+1, input);
else
return match(reg, nextInput);
}
else if (rSubReg[0] =='+')
{
if (nextInput == NULL)
return NULL;
else
{
char newReg[MAX_REGSTR_LEN] = {'\0'};
strcpy(newReg,reg);
newReg[rSubReg-reg] = '*';
return match(newReg, nextInput);
}
}
else if (rSubReg[0] =='?')
{
if (nextInput == NULL)
return match(rSubReg+1, input);
else
return match(rSubReg+1, nextInput);
}
else
{
/* 无运算符时 */
if (nextInput == NULL)
return NULL;
else
return match(rSubReg, nextInput);
}
return NULL;
}
/************************************************************************/
/* 表达式解析 API(处理所有单目运算符) */
/************************************************************************/
char* match(char * reg,char* input )
{
char *rSubReg;
char *nextInput;
int m;
if (strlen(reg)==0)
{
/*printf("The rest input [%s]\n",input);*/
return input;
}
if (reg[0] == '[')
{
m = 1;
while(m < (int)strlen(reg))
{
if (reg[m] == ']')
break;
m++;
}
if (m == (int)strlen(reg))
return NULL;
rSubReg = reg + m + 1;
if (reg[m+1] == '{') /*为了兼容 '2{0}'这种类型的表达式,将大括号运算单独归类*/
return matchBigBracket(reg, input);
if (findAt(reg+1, m-1, input[0]))
nextInput = input+1;
else
nextInput = NULL;
return matchOperate(reg, input, rSubReg, nextInput);
}
if (reg[0] == '(')
{
char subReg[MAX_REGSTR_LEN] = {'\0'};
if (getSmallBracketString(subReg, reg)==false)
return NULL;
char *rSubReg = reg + strlen(subReg) + strlen("()");
if (rSubReg[0] == '{')
return matchBigBracket(reg, input);
char *nextInput =twMatch(subReg, input);
return matchOperate(reg, input, rSubReg, nextInput);
}
if (reg[0] == '.' || ('0'<=reg[0] && reg[0]<='9')||
('a'<=reg[0] && reg[0]<='z') || ('A'<=reg[0] && reg[0]<='Z'))
{
char *rSubReg = reg+1;
char *nextInput;
if (reg[1] == '{')
return matchBigBracket(reg, input);
if (reg[0] == '.')
nextInput = input+1;
else
{
if (reg[0] == input[0])
nextInput = input+1;
else
nextInput = NULL;
}
return matchOperate(reg, input, rSubReg, nextInput);
}
return NULL;
}
/************************************************************************/
/* 加入对双目运算|的解析 */
/************************************************************************/
char* twMatch(char * reg,char* input )
{
char* nextInput ;
char subReg[MAX_REGSTR_LEN]={'\0'};
int n = 0;
int nBracket = 0;
while(n < (int)strlen(reg))
{
if (reg[n] == '(')
nBracket++ ;
else if (reg[n] == ')')
nBracket--;
if (reg[n]=='|' && nBracket==0) /* 处理带小括号的 eg: 1(2|4+3)*|34 */
{
strncpy(subReg,reg,n);
nextInput = match(subReg,input);
if (nextInput == NULL || (nextInput!=NULL&&strlen(nextInput)!=0))
{
return twMatch(reg+n+1,input);
}
else
return nextInput;
}
n++;
}
return match(reg,input);
}
/************************************************************************/
/* 封装的C语言精确匹配正则表达式函数 */
/************************************************************************/
bool cMatch(char * reg,char* input )
{
char* nextInput = twMatch(reg,input);
if (nextInput!=NULL && strlen(nextInput)==0)
return true;
else
return false;
}
/************************************************************************/
/* */
/************************************************************************/
void allMatch(char * reg,char* input)
{
char stmp[MAX_REGSTR_LEN] = {'\0'};
int n = 0;
bool find = false;
printf("%-30s %-20s ",reg,input);
for (; n<=(int)strlen(input); n++)
{
strncpy(stmp, input, n);
if (cMatch(reg,stmp))
{
find = true;
printf("\"%s\" ",stmp);
}
}
if (!find)
{
printf("null ");
}
printf("\n");
}
/*
"3{4}" "3334" null
"1|2|3" 123" "1"
"1*" "11123" "","1","11","111"
"1*([23])?|([234])*" "111234" "", "1","11","111","1112","11123","111234"
*/
int main()
{
printf("The cases in assignments:\n");
allMatch("3{4}","3334");//"1|2|3" 123" "1"
allMatch("1|2|3","123");
allMatch("1*","11123");
allMatch("1*([23])?|([234])*","111234");
/*这个例子按照标准正则表达式规则处理 与grep 和 java正则表达式匹配相同*/
printf("\n\n");
printf("Some other cases:\n");
allMatch("2*|(((3)+5)|67)|[3456]+","333575");
allMatch("2*|(((3)+5)|67)|[3456]+","22");
allMatch("2*|(((3)+5)|67)|[3456]+","678");
allMatch("3.[214]{5}6","32121416");
allMatch("13|2","14");
allMatch("([123]*4)+6","13246");
printf("\n\n");
return 0;
}