- 添加 LocationType 常量定义替代硬编码字符串 - 优化 MatchResult、ExactMatcher、NamedMatcher 结构体字段顺序 - RadixTree.Insert 添加 locationType 参数用于调试追踪 - 更新测试代码适配新接口 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
82 lines
1.9 KiB
Go
82 lines
1.9 KiB
Go
package matcher
|
|
|
|
import (
|
|
"regexp"
|
|
|
|
"github.com/valyala/fasthttp"
|
|
)
|
|
|
|
// RegexMatcher 正则匹配 + 捕获组
|
|
type RegexMatcher struct {
|
|
pattern *regexp.Regexp
|
|
handler fasthttp.RequestHandler
|
|
captures map[string]string
|
|
priority int
|
|
caseInsensitive bool
|
|
}
|
|
|
|
// NewRegexMatcher 创建正则匹配器
|
|
func NewRegexMatcher(pattern string, handler fasthttp.RequestHandler, priority int, caseInsensitive bool) (*RegexMatcher, error) {
|
|
re, err := regexp.Compile(pattern)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &RegexMatcher{
|
|
pattern: re,
|
|
handler: handler,
|
|
priority: priority,
|
|
caseInsensitive: caseInsensitive,
|
|
captures: make(map[string]string),
|
|
}, nil
|
|
}
|
|
|
|
// MustRegexMatcher 创建正则匹配器,失败时 panic
|
|
func MustRegexMatcher(pattern string, handler fasthttp.RequestHandler, priority int, caseInsensitive bool) *RegexMatcher {
|
|
m, err := NewRegexMatcher(pattern, handler, priority, caseInsensitive)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return m
|
|
}
|
|
|
|
// Match 检查路径是否正则匹配
|
|
func (m *RegexMatcher) Match(path string) bool {
|
|
return m.pattern.MatchString(path)
|
|
}
|
|
|
|
// Result 返回匹配结果
|
|
func (m *RegexMatcher) Result() *MatchResult {
|
|
locType := LocationTypeRegex
|
|
if m.caseInsensitive {
|
|
locType = LocationTypeRegexCaseless
|
|
}
|
|
return &MatchResult{
|
|
Handler: m.handler,
|
|
Path: m.pattern.String(),
|
|
Priority: m.priority,
|
|
LocationType: locType,
|
|
Captures: m.captures,
|
|
}
|
|
}
|
|
|
|
// GetCaptures 获取正则捕获组
|
|
func (m *RegexMatcher) GetCaptures(path string) map[string]string {
|
|
matches := m.pattern.FindStringSubmatch(path)
|
|
if matches == nil {
|
|
return nil
|
|
}
|
|
|
|
result := make(map[string]string)
|
|
names := m.pattern.SubexpNames()
|
|
for i, name := range names {
|
|
if i == 0 {
|
|
continue
|
|
}
|
|
if name != "" && i < len(matches) {
|
|
result[name] = matches[i]
|
|
}
|
|
}
|
|
return result
|
|
}
|