How to use regexp get url pattern in golang?

21,430

Solution 1

http.HandleFunc() can not be used to register a pattern to match a regular expression. In short, the pattern specified at HandleFunc() can match a fixed, rooted path (like /favico.ico) or rooted subtrees (like /images/), longer patterns take precedence over shorter ones. You can find more details at the doc of the ServeMux type.

What you can do is register your handler to a rooted subtree which may be everything with the / pattern, and inside your handler you can do further regexp matching and routing.

For example:

func main() {
    http.HandleFunc("/", route) // Match everything
    http.ListenAndServe(":8080", nil)
}

var rNum = regexp.MustCompile(`\d`)  // Has digit(s)
var rAbc = regexp.MustCompile(`abc`) // Contains "abc"

func route(w http.ResponseWriter, r *http.Request) {
    switch {
    case rNum.MatchString(r.URL.Path):
        digits(w, r)
    case rAbc.MatchString(r.URL.Path):
        abc(w, r)
    default:
        w.Write([]byte("Unknown Pattern"))
    }
}

func digits(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("Has digits"))
}

func abc(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("Has abc"))
}

Or use an external library like Gorilla MUX.

Solution 2

I use github.com/gorilla/mux package. So router looks like:

func main() {

    r := mux.NewRouter()

    r.HandleFunc("/{name:pattern}", handle)
    http.ListenAndServe(":8080", r)
}

where {name:pattern} could be simply {slug} (without pattern) or {id:[0-9]+} or combination of them /{category}/{id:[0-9]+}. And get them in handler func:

func handle(w http.ResponseWriter, r *http.Request) {

    params := mux.Vars(r)

    // for /{category}/{id:[0-9]+} pattern
    category := params["category"]
    id := params["id"]
}

run it and try curl http://localhost:8080/whatever/1

Solution 3

Golang doesn't have built-in regex support for URL matching. And it's somewhat complicated to implement from scratch.

Maybe using a framework would be a better choice, such as beego or martin, etc.

Share:
21,430
xichen
Author by

xichen

Updated on July 09, 2022

Comments

  • xichen
    xichen almost 2 years

    How to use regular expression matching URL, which does decide to use the corresponding function processing

    package main
    
    import(
      "fmt"
      "net/http"
    )
    
    func main() {
      http.HandleFunc("/pattern", resolve)
      http.ListenAndServe(":8080", nil)
    }
    
    func resolve(w http.ResponseWriter, r * http.Request) {
      fmt.Println(r.URL.Host)
    }