需求如下,某SP下发短信到短信网关,短信网关做了模板限制,只可以下发模板如:
尊敬的:%客户,你的登录用户名是:%s,登录密码是:%s,当前积分是%。【发达超市】
其中%匹配任意个字符,如果下发短信的文本是:
尊敬的:张三客户,你的登录用户名是:freeland,登录密码是:12345678,当前积分是1234。【发达超市】
短信网关需要把%匹配的红色字体部分的实参文字匹配出来。
其中第1个%匹配 张三
其中第2个%匹配freeland
其中第3个%匹配12345678
其中第3个%匹配1234
下面的源码就实现了根据模板从文本中提取实参的功能。
void StringCut(char *pStrIn, char *pCutFlag, int &nCutCount, char *pStrOut[], int nLength[])
{
char *p1, *p2;
int nStrInLen;
int nCutFlagLen;
p1 = pStrIn;
nStrInLen = strlen(pStrIn);
nCutFlagLen = strlen(pCutFlag);
int i;
i = 0;
p2 = strstr(pStrIn, pCutFlag);
if (NULL == p2)
{
nCutCount = 1;
pStrOut[0] = pStrIn;
nLength[0] = nStrInLen;
}
else
{
while(true)
{
p2 = strstr(p1, pCutFlag);
if (NULL == p2)
{
pStrOut[i] = p1;
nLength[i] = pStrIn + nStrInLen - p1;
i++;
break;
}
*p2 = '\0';
pStrOut[i] = p1;
nLength[i] = p2-p1;
p1 = p2;
p1 += nCutFlagLen;
i++;
}
nCutCount = i;
}
}
int UssdParseVarValue(char* sText, char* sTemplate, char* sMatchString, char* sTextCopy, int &nParaCount, char* sParaArray[], int nParaLength[])
{
strcpy(sTextCopy, sText);
if(strcmp(sText, "") == 0)
{
nParaCount = 1;
sParaArray[0] = sTextCopy;
return 0;
}
char sTemplateCopy[1024*16];
strcpy(sTemplateCopy, sTemplate);
int nItem;
char* sItem[1024];
int nItemLength[1024];
StringCut(sTemplateCopy, sMatchString, nItem, sItem, nItemLength);
int nPart;
nPart = nItem;
bool bHeadPer;
if(strcmp(sItem[0], "") == 0)
{
bHeadPer = true;
nPart--;
}
else
{
bHeadPer = false;
}
bool bTailPer;
if(strcmp(sItem[nItem-1], "") == 0)
{
bTailPer = true;
nPart--;
}
else
{
bTailPer = false;
}
nParaCount = nItem - 1;
//
char* sPartArray[1024];
int nPartLength[1024];
int i;
if(bHeadPer == true)
{
for (i = 0; i < nPart; i++)
{
sPartArray[i] = sItem[i+1];
nPartLength[i] = nItemLength[i+1];
}
}
else
{
for (i = 0; i < nPart; i++)
{
sPartArray[i] = sItem[i];
nPartLength[i] = nItemLength[i];
}
}
//
int nLength;
nLength = strlen(sTextCopy);
char* pShift;
pShift = sTextCopy;
for (i = 0; i < nPart; i++)
{
char* pFind;
pFind = strstr(pShift, sPartArray[i]);
memset(pFind, 0, nPartLength[i]);
pShift = pFind + nPartLength[i];
}
char** sValueArray = sParaArray;
if(bHeadPer == false)
{
i = 0;
char* pBase;
pBase = sTextCopy;
pShift = pBase;
while(pShift <= sTextCopy + nLength)
{
if(pShift - pBase == nPartLength[i])
{
sValueArray[i] = pShift;
nParaLength[i] = strlen(pShift);
pShift += nParaLength[i] + 1;
pBase = pShift-1;
i++;
}
else
{
pShift++;
}
}
}
else
{
i = 0;
sValueArray[i] = sTextCopy;
nParaLength[i] = strlen(sTextCopy);
char* pBase;
pBase = sTextCopy + nParaLength[i];
pShift = pBase;
i++;
while(pShift <= sTextCopy + nLength)
{
if(pShift - pBase == nPartLength[i-1])
{
sValueArray[i] = pShift;
nParaLength[i] = strlen(pShift);
pShift += nParaLength[i] + 1;
pBase = pShift-1;
i++;
}
else
{
pShift++;
}
}
}
return 0;
}
int main(int argc, char* argv[])
{
char* sTemplate = "尊敬的:%客户,你的登录用户名是:%,登录密码是:%,当前积分是%。【发达超市】";
char* sText = "尊敬的:张三客户,你的登录用户名是:freeland,登录密码是:12345678,当前积分是1234。【发达超市】";
int nPara;
char* sParaValue[32];
int nParaLength[32];
char sDestText[1024*8];
UssdParseVarValue(sText, sTemplate, "%", sDestText, nPara, sParaValue, nParaLength);
int i;
for (i = 0; i < nPara; i++)
{
printf("%s\r\n", sParaValue[i]);
}
return 0;
}
用VC编译运行,结果如下图: