mirror of
https://github.com/HDT3213/godis.git
synced 2025-10-04 16:32:41 +08:00
76 lines
1.5 KiB
Go
76 lines
1.5 KiB
Go
package wildcard
|
|
|
|
import (
|
|
"errors"
|
|
"regexp"
|
|
"strings"
|
|
)
|
|
|
|
// Pattern represents a wildcard pattern
|
|
type Pattern struct {
|
|
exp *regexp.Regexp
|
|
}
|
|
|
|
var replaceMap = map[byte]string{
|
|
// characters in the wildcard that must be escaped in the regexp
|
|
'+': `\+`,
|
|
')': `\)`,
|
|
'$': `\$`,
|
|
'.': `\.`,
|
|
'{': `\{`,
|
|
'}': `\}`,
|
|
'|': `\|`,
|
|
'*': ".*",
|
|
'?': ".",
|
|
}
|
|
|
|
// CompilePattern convert wildcard string to Pattern
|
|
func CompilePattern(src string) (*Pattern, error) {
|
|
regexSrc := strings.Builder{}
|
|
regexSrc.WriteByte('^')
|
|
for i := 0; i < len(src); i++ {
|
|
ch := src[i]
|
|
if ch == '\\' {
|
|
if i == len(src)-1 {
|
|
return nil, errors.New("end with escape \\")
|
|
}
|
|
regexSrc.WriteByte(ch)
|
|
regexSrc.WriteByte(src[i+1])
|
|
i++ // skip escaped character
|
|
} else if ch == '^' {
|
|
if i == 0 {
|
|
regexSrc.WriteString(`\^`)
|
|
} else if i == 1 {
|
|
if src[i-1] == '[' {
|
|
regexSrc.WriteString(`^`) // src is: [^
|
|
} else {
|
|
regexSrc.WriteString(`\^`)
|
|
}
|
|
} else {
|
|
if src[i-1] == '[' && src[i-2] != '\\' {
|
|
regexSrc.WriteString(`^`) // src is: [^, except \[^
|
|
} else {
|
|
regexSrc.WriteString(`\^`)
|
|
}
|
|
}
|
|
} else if escaped, toEscape := replaceMap[ch]; toEscape {
|
|
regexSrc.WriteString(escaped)
|
|
} else {
|
|
regexSrc.WriteByte(ch)
|
|
}
|
|
}
|
|
regexSrc.WriteByte('$')
|
|
re, err := regexp.Compile(regexSrc.String())
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &Pattern{
|
|
exp: re,
|
|
}, nil
|
|
}
|
|
|
|
// IsMatch returns whether the given string matches pattern
|
|
func (p *Pattern) IsMatch(s string) bool {
|
|
return p.exp.Match([]byte(s))
|
|
}
|