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
|
||
}
|