www.pudn.com > StringM.rar > StringMatch.cpp


/*---------------------------------------------// 
作者:  苗人头领 
Email: gjjj2002@sina.com 
oicq:  7656312 
 
使用方法: 直接拷贝代码 
//---------------------------------------------*/ 
 
#include  
#include  
/*---------------------------------------------// 
作者:  苗人头领 
Email: gjjj2002@sina.com 
oicq:  7656312 
 
使用方法: 直接拷贝代码 
//---------------------------------------------*/ 
 
 
//功  能:在lpszSour中查找字符串lpszFind,lpszFind中可以包含通配字符‘?’ 
//参  数:nStart为在lpszSour中的起始查找位置 
//返回值:成功返回匹配位置,否则返回-1 
//注  意:Called by “bool MatchingString()” 
int FindingString(const char* lpszSour, const char* lpszFind, int nStart /* = 0 */) 
{ 
//	ASSERT(lpszSour && lpszFind && nStart >= 0); 
	if(lpszSour == NULL || lpszFind == NULL || nStart < 0) 
		return -1; 
 
	int m = strlen(lpszSour); 
	int n = strlen(lpszFind); 
 
	if( nStart+n > m ) 
		return -1; 
 
	if(n == 0) 
		return nStart; 
 
//KMP算法 
	int* next = new int[n]; 
	//得到查找字符串的next数组 
	{	n--; 
 
		int j, k; 
		j = 0; 
		k = -1; 
		next[0] = -1; 
 
		while(j < n) 
		{	if(k == -1 || lpszFind[k] == '?' || lpszFind[j] == lpszFind[k]) 
			{	j++; 
				k++; 
				next[j] = k; 
			} 
			else 
				k = next[k]; 
		} 
 
		n++; 
	} 
 
	int i = nStart, j = 0; 
	while(i < m && j < n) 
	{ 
		if(j == -1 || lpszFind[j] == '?' || lpszSour[i] == lpszFind[j]) 
		{	i++; 
			j++; 
		} 
		else 
			j = next[j]; 
	} 
 
	delete []next; 
 
	if(j >= n) 
		return i-n; 
	else 
		return -1; 
} 
 
//功	  能:带通配符的字符串匹配 
//参	  数:lpszSour是一个普通字符串; 
//			  lpszMatch是一可以包含通配符的字符串; 
//			  bMatchCase为0,不区分大小写,否则区分大小写。 
//返  回  值:匹配,返回1;否则返回0。 
//通配符意义: 
//		‘*’	代表任意字符串,包括空字符串; 
//		‘?’	代表任意一个字符,不能为空; 
//时	  间:	2001.11.02	13:00 
bool MatchingString(const char* lpszSour, const char* lpszMatch, bool bMatchCase /*  = true */) 
{ 
//	ASSERT(AfxIsValidString(lpszSour) && AfxIsValidString(lpszMatch)); 
	if(lpszSour == NULL || lpszMatch == NULL) 
		return false; 
 
	if(lpszMatch[0] == 0)//Is a empty string 
	{ 
		if(lpszSour[0] == 0) 
			return true; 
		else 
			return false; 
	} 
 
	int i = 0, j = 0; 
 
	//生成比较用临时源字符串'szSource' 
	char* szSource = 
		new char[ (j = strlen(lpszSour)+1) ]; 
 
	if( bMatchCase ) 
	{	//memcpy(szSource, lpszSour, j); 
		while( *(szSource+i) = *(lpszSour+i++) ); 
	} 
	else 
	{	//Lowercase 'lpszSour' to 'szSource' 
		i = 0; 
		while(lpszSour[i]) 
		{	if(lpszSour[i] >= 'A' && lpszSour[i] <= 'Z') 
				szSource[i] = lpszSour[i] - 'A' + 'a'; 
			else 
				szSource[i] = lpszSour[i]; 
 
			i++; 
		} 
		szSource[i] = 0; 
	} 
 
	//生成比较用临时匹配字符串'szMatcher' 
	char* szMatcher = new char[strlen(lpszMatch)+1]; 
 
	//把lpszMatch里面连续的“*”并成一个“*”后复制到szMatcher中 
	i = j = 0; 
	while(lpszMatch[i]) 
	{ 
		szMatcher[j++] = (!bMatchCase) ? 
								( (lpszMatch[i] >= 'A' && lpszMatch[i] <= 'Z') ?//Lowercase lpszMatch[i] to szMatcher[j] 
										lpszMatch[i] - 'A' + 'a' : 
										lpszMatch[i] 
								) : 
								lpszMatch[i];		 //Copy lpszMatch[i] to szMatcher[j] 
		//Merge '*' 
		if(lpszMatch[i] == '*') 
			while(lpszMatch[++i] == '*'); 
		else 
			i++; 
	} 
	szMatcher[j] = 0; 
 
	//开始进行匹配检查 
 
	int nMatchOffset, nSourOffset; 
 
	bool bIsMatched = true; 
	nMatchOffset = nSourOffset = 0; 
	while(szMatcher[nMatchOffset]) 
	{ 
		if(szMatcher[nMatchOffset] == '*') 
		{ 
			if(szMatcher[nMatchOffset+1] == 0) 
			{	//szMatcher[nMatchOffset]是最后一个字符 
 
				bIsMatched = true; 
				break; 
			} 
			else 
			{	//szMatcher[nMatchOffset+1]只能是'?'或普通字符 
 
				int nSubOffset = nMatchOffset+1; 
 
				while(szMatcher[nSubOffset]) 
				{	if(szMatcher[nSubOffset] == '*') 
						break; 
					nSubOffset++; 
				} 
 
				if( strlen(szSource+nSourOffset) < 
						size_t(nSubOffset-nMatchOffset-1) ) 
				{	//源字符串剩下的长度小于匹配串剩下要求长度 
					bIsMatched = false; //判定不匹配 
					break;			//退出 
				} 
 
				if(!szMatcher[nSubOffset])//nSubOffset is point to ender of 'szMatcher' 
				{	//检查剩下部分字符是否一一匹配 
 
					nSubOffset--; 
					int nTempSourOffset = strlen(szSource)-1; 
					//从后向前进行匹配 
					while(szMatcher[nSubOffset] != '*') 
					{ 
						if(szMatcher[nSubOffset] == '?') 
							; 
						else 
						{	if(szMatcher[nSubOffset] != szSource[nTempSourOffset]) 
							{	bIsMatched = false; 
								break; 
							} 
						} 
						nSubOffset--; 
						nTempSourOffset--; 
					} 
					break; 
				} 
				else//szMatcher[nSubOffset] == '*' 
				{	nSubOffset -= nMatchOffset; 
 
					char* szTempFinder = new char[nSubOffset]; 
					nSubOffset--; 
					memcpy(szTempFinder, szMatcher+nMatchOffset+1, nSubOffset); 
					szTempFinder[nSubOffset] = 0; 
 
					int nPos = ::FindingString(szSource+nSourOffset, szTempFinder, 0); 
					delete []szTempFinder; 
 
					if(nPos != -1)//在'szSource+nSourOffset'中找到szTempFinder 
					{	nMatchOffset += nSubOffset; 
						nSourOffset += (nPos+nSubOffset-1); 
					} 
					else 
					{	bIsMatched = false; 
						break; 
					} 
				} 
			} 
		}		//end of "if(szMatcher[nMatchOffset] == '*')" 
		else if(szMatcher[nMatchOffset] == '?') 
		{ 
			if(!szSource[nSourOffset]) 
			{	bIsMatched = false; 
				break; 
			} 
			if(!szMatcher[nMatchOffset+1] && szSource[nSourOffset+1]) 
			{	//如果szMatcher[nMatchOffset]是最后一个字符, 
				//且szSource[nSourOffset]不是最后一个字符 
				bIsMatched = false; 
				break; 
			} 
			nMatchOffset++; 
			nSourOffset++; 
		} 
		else//szMatcher[nMatchOffset]为常规字符 
		{ 
			if(szSource[nSourOffset] != szMatcher[nMatchOffset]) 
			{	bIsMatched = false; 
				break; 
			} 
			if(!szMatcher[nMatchOffset+1] && szSource[nSourOffset+1]) 
			{	bIsMatched = false; 
				break; 
			} 
			nMatchOffset++; 
			nSourOffset++; 
		} 
	} 
 
	delete []szSource; 
	delete []szMatcher; 
	return bIsMatched; 
} 
 
 
//-------------使用例子----------------// 
 
 
 
void main() 
{ 
	char* str = "String match"; 
	bool bMatch; 
	char* sMatch; 
 
	sMatch = "*ing??*c*"; 
	bMatch = MatchingString(str, sMatch,0);//单匹配 
	printf("\"%s\" %s match with \"%s\"\n\n", str, bMatch ? "is" : "is not", sMatch); 
 
	sMatch = "*ing??*c*??"; 
	bMatch = MatchingString(str, sMatch,0);//单匹配 
	printf("\"%s\" %s match with \"%s\"\n\n", str, bMatch ? "is" : "is not", sMatch); 
 
	 
}