1 ///@brief 使用空白字符匹配
2 #define USE_WHITE_SPACE_MATCH
3
4 /*!
5 * @brief 匹配一個字符串模版
6 * @param pszText 需要匹配的字符串
7 * @param uTextLen 需要匹配的字符串長度
8 * @param pszTemplateText 需要匹配的模版字符串
9 * @param uTemplateTextLen 需要匹配的模版字符串的長度
10 * @param pMatchedLen 返回的完成匹配的字符串長度
11 * @return 返回是否匹配成功
12 * @retval true on 匹配成功
13 * @retval false on 匹配失敗
14 */
15 bool _MatchTemplate( const wchar_t * pszText, size_t uTextLen, const wchar_t * pszTemplateText, size_t uTemplateTextLen, size_t * pMatchedLen )
16 {
17
18 size_t uTextPos = 0u, uTemplateTextPos = 0u;
19 size_t uLastStarPos = ~(size_t)0u;
20
21 // 沒有匹配的模版,直接匹配成功
22 if( uTemplateTextLen == 0 )
23 {
24 if( pMatchedLen != NULL )
25 *pMatchedLen = uTextPos;
26 return true;
27 }
28 while( true )
29 {
30 wchar_t cTemplate = pszTemplateText[uTemplateTextPos];
31 switch( cTemplate )
32 {
33 #ifdef USE_WHITE_SPACE_MATCH
34 case L'.':
35 {
36 if( pszText[uTextPos] != 0x20 &&
37 pszText[uTextPos] != 0x3000 )
38 {
39 if( pMatchedLen != NULL )
40 *pMatchedLen = uTextPos;
41 return false;
42 }
43 ++uTemplateTextPos;
44 ++uTextPos;
45 }
46 break;
47 #endif
48 case L'?':
49 {
50 ++uTemplateTextPos;
51 ++uTextPos;
52 }
53 break;
54 case L'*':
55 {
56 if( uTemplateTextPos >= uTemplateTextLen-1 )
57 {
58 // 結尾的*,直接認為是匹配所有字符(包括空)
59 if( pMatchedLen != NULL )
60 *pMatchedLen = uTextLen;
61 return true;
62 }
63
64 wchar_t cNextTemplate = pszTemplateText[uTemplateTextPos+1];
65 // 跳過重復的*
66 if( cNextTemplate == '*' )
67 {
68 ++uTemplateTextPos;
69 break;
70 }
71 // 記錄最后一個*的出現(xiàn)位置
72 if( uLastStarPos != uTemplateTextPos )
73 uLastStarPos = uTemplateTextPos;
74 // 檢查下一個模版字符是否匹配
75
76 // ?匹配直接跳過
77 if( cNextTemplate == '?' )
78 {
79 uTemplateTextPos+= 2;
80 }
81 #ifdef USE_WHITE_SPACE_MATCH
82 // 空格匹配
83 else if( cNextTemplate == '.' )
84 {
85 if( pszText[uTextPos] == 0x20 ||
86 pszText[uTextPos] == 0x3000 )
87 {
88 uTemplateTextPos+=2;
89 }
90 }
91 #endif
92 // 字符匹配
93 else if( cNextTemplate == pszText[uTextPos] )
94 {
95 uTemplateTextPos+=2;
96 }
97 // 下一個字符
98 ++uTextPos;
99 }
100 break;
101 default:
102 if( cTemplate != pszText[uTextPos] )
103 {
104 // 如果遇到過*就回退到最后一個*
105 if( uLastStarPos < uTemplateTextLen )
106 {
107 uTemplateTextPos = uLastStarPos;
108 cTemplate = pszTemplateText[uTemplateTextPos];
109 ++uTextPos;
110 break;
111 }
112 if( pMatchedLen != NULL )
113 *pMatchedLen = uTextPos;
114 return false;
115
116 }
117 ++uTextPos;
118 ++uTemplateTextPos;
119 break;
120 }
121 // 成功匹配完城所有的
122 if( uTemplateTextPos >= uTemplateTextLen )
123 {
124 break;
125 }
126 // 沒有成功匹配完整個模版,文字就沒有了
127 if( uTextPos >= uTextLen )
128 {
129 if( pMatchedLen != NULL )
130 *pMatchedLen = uTextPos;
131 return false;
132 }
133 }
134 if( pMatchedLen != NULL )
135 *pMatchedLen = uTextPos;
136 return true;
137 }
138
模版支持三種匹配符號 '*','?','.'
*匹配任意多個任意字符串
?匹配一個字符串
.匹配一個空格
可以通過注釋掉宏來禁止匹配空格
達到的效果和文件系統(tǒng)的文件名匹配差不多
關于遞歸的方法:
VCZH提供了一個遞歸的解法,并且“寥寥數(shù)行,瞬間搞定”。
不過,遞歸會帶來堆棧的問題。
而且他的方法里存在BUG,我就不貼上來了。
據(jù)他稱那種方法來自一本 beautiful code的書。此書我沒看過,所以不清楚。
從他的方法本身看,他只能提供是否匹配的一個結果,并且匹配模版和待匹配的字符串必須是0結尾,并且不返回結束匹配時的匹配進度。
并且在處理*的時候,有些許小BUG。
雖然他一直在堅持自己是在做學術研究,也有不少人匿名來支持他,不過我覺得他還是有些態(tài)度問題。
總是喜歡在別人的貼上表現(xiàn)自己。做的太過了就是顯擺了。
從他回帖說的那些話,比如“寥寥數(shù)行,瞬間搞定”這些,以及并不完善的代碼看來,他根本就沒有看過我的代碼,只是憑字面意思就開始貼代碼。
我實在不清楚他說這些話和貼代碼的原因是什么。這些我就不再討論了,我也刪除了他的回復。
不過我想說,如果你一直以這種態(tài)度來回別人的帖子,那你會成為一個令人討厭的人。