dongxia9620 2013-05-17 20:24
浏览 60
已采纳

路由http请求时,Weird Go正则表达式不匹配

I'm serving web content via a Go web server and using regular expressions to match handlers to request paths. I've noticed a really strange behaviour I've diluted to this test code below. Basically, any 8 letter/number combination is meant to be caught by a handler, while other specific request paths are meant to be caught by other handlers. This works great by in the case of the 8 letter/number path the match gets picked up by the first handler if the letter sequence ends in a lower case 'c'. Any other letter at the end works fine.

The code below can be pasted into a file and run. It will serve on localhost:8080. I've provided a few request links to demonstrate the problem.

package main

import (
    "fmt"
    "net/http" 
    "regexp"
) 

// This is the handler when passing a string of 8 characters ([])
func runTest(w http.ResponseWriter, r *http.Request) {
    path := r.URL.Path[1:]
    fmt.Fprintf(w, path)
} 

func runTest2(w http.ResponseWriter, r *http.Request) {
    path := "Reg ex for: .[(css|jpg|png|js|ttf|ico)]$" 
    fmt.Fprintf(w, path)
} 

func runTest3(w http.ResponseWriter, r *http.Request) {
    path := "Reg ex for: /all$" 
    fmt.Fprintf(w, path)
} 

// Regular expression handler
type route struct {
    pattern *regexp.Regexp
    handler http.Handler
}

type RegexpHandler struct {
    routes []*route
}

func (h *RegexpHandler) Handler(pattern *regexp.Regexp, handler http.Handler) {
    h.routes = append(h.routes, &route{pattern, handler})
}

func (h *RegexpHandler) HandleFunc(pattern *regexp.Regexp, handler func(http.ResponseWriter, *http.Request)) {
    h.routes = append(h.routes, &route{pattern, http.HandlerFunc(handler)})
}

func (h *RegexpHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    for _, route := range h.routes {
        if route.pattern.MatchString(r.URL.Path) {
            route.handler.ServeHTTP(w, r)
            return
        }
    }
    http.NotFound(w, r)

}

func main() {
    handler := &RegexpHandler{} 
     handler.HandleFunc(regexp.MustCompile(`.[(css|jpg|png|js|ttf|ico)]$`), runTest2)
     handler.HandleFunc(regexp.MustCompile("^/all$"), runTest3) 
    handler.HandleFunc(regexp.MustCompile("^/[A-Z0-9a-z]{8}$"), runTest)  
    http.ListenAndServe(":8080", handler)
}

This request gets picked up by the second handler (runTest3):

http://localhost:8080/all

This request gets picked up by the third handler (runTest) which prints out the path portion of the url:

http://localhost:8080/yr22FBMD.

This request however, gets picked up by the first handler (note its ending with a lower case c):

http://localhost:8080/yr22FBMc

Any ideas? This is extremely weird!

  • 写回答

1条回答 默认 最新

  • dsklfsdlkf1232 2013-05-17 20:38
    关注

    You have the extensions inside brackets in runTest2. This makes it a character class so your regex is saying, "match any line with '(' 'c', 's', '|', 'j', 'p', 'g', 'n', 't', 'f', 'i', 'o', or ')' as the last character.

    You just need to remove the sqaure brackets, and I think you mean to escape the period at the beginning.

    "\.(css|jpg|png|js|ttf|ico)$"
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!
  • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?