xichen
xichen

Reputation: 361

How to use regexp get url pattern in golang?

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

Upvotes: 8

Views: 28881

Answers (3)

vladkras
vladkras

Reputation: 17227

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

Upvotes: 4

icza
icza

Reputation: 418187

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.

Upvotes: 13

Jiang
Jiang

Reputation: 588

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.

Upvotes: 1

Related Questions