| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 |
- // Package wildcard 实现了通配符模式匹配功能
- package wildcard
- const (
- normal = iota // 普通字符
- all // * 匹配任意数量字符
- anySymbol // ? 匹配单个字符
- setSymbol // [] 字符集匹配
- rangSymbol // [a-b] 范围匹配
- negSymbol // [^a] 否定匹配
- )
- // item 表示模式中的一个元素
- type item struct {
- character byte // 字符值
- set map[byte]bool // 字符集合
- typeCode int // 类型码
- }
- // contains 检查字符是否匹配当前元素
- func (i *item) contains(c byte) bool {
- switch i.typeCode {
- case setSymbol:
- _, ok := i.set[c]
- return ok
- case rangSymbol:
- if _, ok := i.set[c]; ok {
- return true
- }
- var (
- _min byte = 255
- _max byte = 0
- )
- for k := range i.set {
- if _min > k {
- _min = k
- }
- if _max < k {
- _max = k
- }
- }
- return c >= _min && c <= _max
- case negSymbol:
- _, ok := i.set[c]
- return !ok
- default:
- return false
- }
- }
- // Pattern 表示一个通配符模式
- type Pattern struct {
- items []*item
- }
- // CompilePattern 将通配符字符串转换为Pattern对象
- //
- // 支持的通配符:
- // * - 匹配任意数量的字符(包括空字符)
- // ? - 匹配单个字符
- // [] - 匹配括号内任意一个字符,如[abc]
- // [a-b] - 匹配范围内的任意字符
- // [^a] - 匹配除括号内字符外的任意字符
- // \ - 转义字符
- func CompilePattern(src string) *Pattern {
- items := make([]*item, 0, len(src)) // 预分配容量
- escape := false
- inSet := false
- var set map[byte]bool
- for _, v := range src {
- c := byte(v)
- if escape {
- // 处理转义字符
- items = append(items, &item{typeCode: normal, character: c})
- escape = false
- } else if c == '*' {
- // 匹配任意数量字符
- items = append(items, &item{typeCode: all})
- } else if c == '?' {
- // 匹配单个字符
- items = append(items, &item{typeCode: anySymbol})
- } else if c == '\\' {
- // 转义下一个字符
- escape = true
- } else if c == '[' {
- // 开始字符集定义
- if !inSet {
- inSet = true
- set = make(map[byte]bool)
- } else {
- set[c] = true
- }
- } else if c == ']' {
- // 结束字符集定义
- if inSet {
- inSet = false
- typeCode := setSymbol
- if _, ok := set['-']; ok {
- typeCode = rangSymbol
- delete(set, '-')
- }
- if _, ok := set['^']; ok {
- typeCode = negSymbol
- delete(set, '^')
- }
- items = append(items, &item{typeCode: typeCode, set: set})
- } else {
- items = append(items, &item{typeCode: normal, character: c})
- }
- } else {
- if inSet {
- set[c] = true
- } else {
- items = append(items, &item{typeCode: normal, character: c})
- }
- }
- }
- return &Pattern{
- items: items,
- }
- }
- // IsMatch 检查给定字符串是否匹配该模式
- // 使用动态规划算法实现
- func (p *Pattern) IsMatch(s string) bool {
- if len(p.items) == 0 {
- return len(s) == 0
- }
- m := len(s)
- n := len(p.items)
- // 使用二维布尔数组进行动态规划
- table := make([][]bool, m+1)
- for i := range table {
- table[i] = make([]bool, n+1)
- }
- // 初始化基本情况
- table[0][0] = true
- // 处理空字符串与模式的匹配情况
- for j := 1; j <= n; j++ {
- if p.items[j-1].typeCode == all {
- table[0][j] = table[0][j-1]
- }
- }
- // 填充动态规划表
- for i := 1; i <= m; i++ {
- for j := 1; j <= n; j++ {
- switch p.items[j-1].typeCode {
- case all:
- // * 可以匹配空字符串或多个字符
- table[i][j] = table[i-1][j] || table[i][j-1]
- case anySymbol:
- // ? 匹配任意单个字符
- table[i][j] = table[i-1][j-1]
- case normal:
- // 普通字符精确匹配
- table[i][j] = table[i-1][j-1] && s[i-1] == p.items[j-1].character
- default:
- // 集合类匹配 [abc], [a-z], [^a] 等
- table[i][j] = table[i-1][j-1] && p.items[j-1].contains(s[i-1])
- }
- }
- }
- return table[m][n]
- }
|