Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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)
}
like image 790
xichen Avatar asked May 27 '15 06:05

xichen


People also ask

How do I match a pattern in regex?

Most characters, including all letters ( a-z and A-Z ) and digits ( 0-9 ), match itself. For example, the regex x matches substring "x" ; z matches "z" ; and 9 matches "9" . Non-alphanumeric characters without special meaning in regex also matches itself. For example, = matches "=" ; @ matches "@" .

What does \\ mean in regex?

\\. matches the literal character . . the first backslash is interpreted as an escape character by the Emacs string reader, which combined with the second backslash, inserts a literal backslash character into the string being read. the regular expression engine receives the string \.

Does GoLang have regex?

The GoLang standard package for writing regular expressions is called regexp . The package uses RE2 syntax standards that are also used by other languages like Python, C, and Perl.


2 Answers

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.

like image 141
icza Avatar answered Sep 20 '22 09:09

icza


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

like image 22
vladkras Avatar answered Sep 18 '22 09:09

vladkras