github.com/sohaha/zlsgo@v1.7.13-0.20240501141223-10dd1a906f76/zstring/match.go (about) 1 package zstring 2 3 import ( 4 "strings" 5 "unicode/utf8" 6 ) 7 8 func Match(str, pattern string) bool { 9 if pattern == "*" { 10 return true 11 } 12 return deepMatch(str, pattern) 13 } 14 15 func deepMatch(str, pattern string) bool { 16 // label: 17 for len(pattern) > 0 { 18 if pattern[0] > 0x7f { 19 return deepMatchRune(str, pattern) 20 } 21 switch pattern[0] { 22 default: 23 if len(str) == 0 { 24 return false 25 } 26 if str[0] > 0x7f { 27 return deepMatchRune(str, pattern) 28 } 29 30 if str[0] != pattern[0] { 31 return false 32 } 33 case '{': 34 i, l := 1, len(pattern) 35 for ; i < l; i++ { 36 if pattern[i] == '}' { 37 break 38 } 39 } 40 if i > 2 { 41 for _, p := range strings.Split(pattern[1:i], ",") { 42 if len(pattern) > i { 43 p = p + pattern[i+1:] 44 } 45 if deepMatch(str, p) { 46 return true 47 } 48 } 49 return false 50 } 51 case '?': 52 if len(str) == 0 { 53 return false 54 } 55 case '*': 56 return deepMatch(str, pattern[1:]) || 57 (len(str) > 0 && deepMatch(str[1:], pattern)) 58 } 59 str = str[1:] 60 pattern = pattern[1:] 61 } 62 return len(str) == 0 && len(pattern) == 0 63 } 64 65 func x7f(str string) (r rune, p int) { 66 if len(str) <= 0 { 67 return utf8.RuneError, 0 68 } 69 var s uint8 = str[0] 70 if s > 0x7f { 71 r, p = utf8.DecodeRuneInString(str) 72 } else { 73 r, p = rune(s), 1 74 } 75 return 76 } 77 78 func deepMatchRune(str, pattern string) bool { 79 var sr, pr rune 80 var srsz, prsz int 81 82 sr, srsz = x7f(str) 83 pr, prsz = x7f(pattern) 84 85 for pr != utf8.RuneError { 86 switch pr { 87 default: 88 if srsz == utf8.RuneError { 89 return false 90 } 91 if sr != pr { 92 return false 93 } 94 case '?': 95 if srsz == utf8.RuneError { 96 return false 97 } 98 case '*': 99 return deepMatchRune(str, pattern[prsz:]) || 100 (srsz > 0 && deepMatchRune(str[srsz:], pattern)) 101 } 102 103 pattern = pattern[prsz:] 104 str = str[srsz:] 105 106 sr, srsz = x7f(str) 107 pr, prsz = x7f(pattern) 108 } 109 110 return srsz == 0 && prsz == 0 111 } 112 113 func IsPattern(str string) bool { 114 for i := 0; i < len(str); i++ { 115 if str[i] == '*' || str[i] == '?' { 116 return true 117 } 118 } 119 return false 120 }