forked from chennqqi/goutils
/
wildcard.go
129 lines (112 loc) · 2.73 KB
/
wildcard.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package utils
//static int wildcmp(const char* wild, const char* pattern)
//{
// // Written by Jack Handy - <A href="mailto:jakkhandy@hotmail.com">jakkhandy@hotmail.com</A>
// const char *cp = NULL, *mp = NULL;
// while ((*pattern) && (*wild != '*'))
// {
// if ((*wild != *pattern) && (*wild != '?'))
// {
// return 0;
// }
// wild++;
// pattern++;
// }
// while (*pattern)
// {
// if (*wild == '*')
// {
// if (!*++wild)
// {
// return 1;
// }
// mp = wild;
// cp = pattern + 1;
// }
// else if ((*wild == *pattern) || (*wild == '?'))
// {
// wild++;
// pattern++;
// }
// else
// {
// wild = mp;
// pattern = cp++;
// }
// }
// while (*wild == '*')
// {
// wild++;
// }
// return !*wild;
//}
//// The main function that checks if two given strings match. The first
//// string may contain wildcard characters
//static bool match(const char *first, const char* second)
//{
// // If we reach at the end of both strings, we are done
// if (*first == '\0' && *second == '\0')
// return true;
// // Make sure that the characters after '*' are present in second string.
// // This function assumes that the first string will not contain two
// // consecutive '*'
// if (*first == '*' && *(first + 1) != '\0' && *second == '\0')
// return false;
// // If the first string contains '?', or current characters of both
// // strings match
// if (*first == '?' || *first == *second)
// return match(first + 1, second + 1);
// // If there is *, then there are two possibilities
// // a) We consider current character of second string
// // b) We ignore current character of second string.
// if (*first == '*')
// return match(first + 1, second) || match(first, second + 1);
// return false;
//}
//wirdcard match, see https://en.wikipedia.org/wiki/Wild_card
func WildcardCmp(txt, pattern string) bool {
txtLen := len(txt)
patternLen := len(pattern)
if patternLen == 0 {
return false
}
var txtIdx int
var patternIdx int
var mark int
for txtIdx < txtLen && patternIdx < patternLen {
if pattern[patternIdx] == '?' {
patternIdx++
txtIdx++
continue
} else if pattern[patternIdx] == '*' {
patternIdx++
mark = patternIdx
continue
}
if pattern[patternIdx] != txt[txtIdx] {
if patternIdx == 0 && txtIdx == 0 {
return false
}
txtIdx -= (patternIdx - mark - 1)
patternIdx = mark
continue
}
txtIdx++
patternIdx++
}
if patternIdx == patternLen {
if txtIdx == txtLen {
return true
}
if pattern[patternIdx-1] == byte('*') {
return true
}
}
for patternIdx < patternLen {
if pattern[patternIdx] != byte('*') {
return false
}
patternIdx++
}
return txtIdx == txtLen
}