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  }