68 lines
1.5 KiB
Go
68 lines
1.5 KiB
Go
|
package server
|
|||
|
|
|||
|
import (
|
|||
|
"net/url"
|
|||
|
"regexp"
|
|||
|
"strings"
|
|||
|
)
|
|||
|
|
|||
|
type UrlParamMatcher struct {
|
|||
|
Params []string
|
|||
|
Reg *regexp.Regexp
|
|||
|
}
|
|||
|
|
|||
|
// 解析URL函数
|
|||
|
// 参数:
|
|||
|
//
|
|||
|
// u:待解析的URL字符串
|
|||
|
//
|
|||
|
// 返回值:
|
|||
|
//
|
|||
|
// 解析后的UrlParamMatcher结构体
|
|||
|
func ParseUrl(u string) UrlParamMatcher {
|
|||
|
ret := UrlParamMatcher{}
|
|||
|
|
|||
|
uo, _ := url.Parse(u)
|
|||
|
|
|||
|
// 判断路径是否非空且非根路径
|
|||
|
if uo.Path != "" && uo.Path != "/" {
|
|||
|
// 将路径按斜杠分割成切片
|
|||
|
us := strings.Split(uo.Path, "/")
|
|||
|
for index, v := range us {
|
|||
|
// 判断是否以冒号开头
|
|||
|
if strings.HasPrefix(v, ":") {
|
|||
|
// 去除冒号前缀
|
|||
|
param := strings.TrimPrefix(v, ":")
|
|||
|
// 将参数添加到Params切片中
|
|||
|
ret.Params = append(ret.Params, param)
|
|||
|
// 将参数名作为正则表达式的命名捕获组
|
|||
|
us[index] = "(?P<" + param + ">.*)"
|
|||
|
}
|
|||
|
}
|
|||
|
// 如果存在参数,则将路径编译为正则表达式
|
|||
|
if len(ret.Params) > 0 {
|
|||
|
ret.Reg, _ = regexp.Compile("^" + strings.Join(us, "/") + "$")
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return ret
|
|||
|
}
|
|||
|
|
|||
|
func MatchUrlParam(u string, matcher *UrlParamMatcher) (map[string]string, bool) {
|
|||
|
if matcher.Reg != nil {
|
|||
|
uo, _ := url.Parse(u)
|
|||
|
if uo.Path == "" || uo.Path == "/" {
|
|||
|
return nil, false
|
|||
|
}
|
|||
|
matches := matcher.Reg.FindStringSubmatch(uo.Path)
|
|||
|
if len(matches) > 0 {
|
|||
|
params := make(map[string]string)
|
|||
|
for i, name := range matcher.Params {
|
|||
|
params[name] = matches[i+1]
|
|||
|
}
|
|||
|
return params, true
|
|||
|
}
|
|||
|
}
|
|||
|
return nil, false
|
|||
|
}
|