// @tag glob package glob // Match checks if a string matches a glob-style pattern. // Supports: // - * (asterisk): matches any sequence of characters (including empty) // - ? (question): matches any single character // // This matches Redis PUBSUB CHANNELS pattern behavior. func Match(pattern, s string) bool { if pattern == "" { return s == "" } if pattern == "*" { return true } // Simple glob matching using dynamic programming // Convert pattern to regex-like matching patternLen := len(pattern) sLen := len(s) // dp[i][j] = true if pattern[0:i] matches s[0:j] dp := make([][]bool, patternLen+1) for i := range dp { dp[i] = make([]bool, sLen+1) } // Empty pattern matches empty string dp[0][0] = true // Handle leading * in pattern for i := 1; i <= patternLen; i++ { if pattern[i-1] == '*' { dp[i][0] = dp[i-1][0] } } // Fill the DP table for i := 1; i <= patternLen; i++ { for j := 1; j <= sLen; j++ { switch pattern[i-1] { case '*': // * matches: either consume nothing (stay at same position in pattern) // or consume one character from string dp[i][j] = dp[i-1][j] || dp[i][j-1] case '?': // ? matches any single character dp[i][j] = dp[i-1][j-1] default: // Literal character must match exactly dp[i][j] = dp[i-1][j-1] && pattern[i-1] == s[j-1] } } } return dp[patternLen][sLen] }