func parsePattern(parent *Node, segments []string) *Node {
	segment := segments[0]
	segments = segments[1:]
	child := parseSegment(parent, segment)
	if len(segments) == 0 {
		child.endpoint = true
		return child
	}
	return parsePattern(child, segments)
}
parsePattern support multi pattern
package mux
import (
	"fmt"
	"net/url"
	"regexp"
	"strings"
)
const Version = "0.0.1"
var (
	allowSuffixExt = []string{".json", ".xml", ".html"}
	extWildRegexp = regexp.MustCompile(`([^.]+).(.+)`)
	wildRegexp = regexp.MustCompile(`(.+)`)
	wordRegexp = regexp.MustCompile(`^\w+$`)
	paramRegexp = regexp.MustCompile(`^:\w+$`)
	optionalParamRegexp = regexp.MustCompile(`^\?:\w+$`)
	defaultOptions = Options{
		CaseSensitive:  true,
		PathClean:      true,
		StrictSlash:    true,
		UseEncodedPath: true,
	}
)
type Options struct {
	CaseSensitive bool
	PathClean bool
	StrictSlash bool
	UseEncodedPath bool
}
func NewTrie(args ...Options) *Trie {
	opts := defaultOptions
	if len(args) > 0 {
		opts = args[0]
	}
	return &Trie{
		caseSensitive:  opts.CaseSensitive,
		pathClean:      opts.PathClean,
		strictSlash:    opts.StrictSlash,
		useEncodedPath: opts.UseEncodedPath,
		root: &Node{
			parent:   nil,
			children: make(map[string]*Node),
			handlers: make(map[string]interface{}),
		},
	}
}
type Trie struct {
	caseSensitive  bool
	pathClean      bool
	strictSlash    bool
	useEncodedPath bool
	root           *Node
}
func (t *Trie) Parse(pattern string) *Node {
	if strings.Contains(pattern, "//") {
		panic(fmt.Errorf(`multi-slash exist: "%s"`, pattern))
	}
	_pattern := strings.TrimPrefix(pattern, "/")
	if !t.caseSensitive {
		_pattern = strings.ToLower(_pattern)
	}
	node := parsePattern(t.root, strings.Split(_pattern, "/"))
	if node.pattern == "" {
		node.pattern = pattern
	}
	return node
}
func (t *Trie) Match(path string) (*Matched, error) {
	if path == "" || path[0] != '/' {
		return nil, fmt.Errorf(`path is not start with "/": "%s"`, path)
	}
	if t.pathClean {
		path = pathClean(path)
	}
	if !t.caseSensitive {
		path = strings.ToLower(path)
	}
	start := 1
	end := len(path)
	matched := new(Matched)
	parent := t.root
	for i := 1; i <= end; i++ {
		if i < end && path[i] != '/' {
			continue
		}
		segment := path[start:i]
		node := matchNode(parent, segment, path[i:])
		if node == nil {
			if parent.endpoint && i == end && segment == "" {
				matched.Path = path[:end-1]
			}
			if i == end {
				for _, ext := range allowSuffixExt {
					if strings.HasSuffix(segment, ext) {
						node = matchNode(parent, strings.TrimSuffix(segment, ext), path[i:])
						if node != nil {
							if matched.Params == nil {
								matched.Params = make(map[string]string)
							}
							matched.Params[":ext"] = ext[1:]
							goto ParentNode
						}
					}
				}
			}
			return matched, nil
		}
	ParentNode:
		parent = node
		if len(parent.name) > 0 {
			if matched.Params == nil {
				matched.Params = make(map[string]string)
			}
			if parent.wildcard {
				if len(parent.name) == 1 {
					segs := strings.Split(path[start:end], "/")
					starValue := []string{}
					for {
						if len(segs) > 0 {
							starValue = append(starValue, segs[0])
						}
						if len(segs) == 1 {
							break
						} else {
							segs = segs[1:]
						}
						n := matchNode(parent, segs[0], strings.Join(segs, "/"))
						if n != nil {
							matched.Params[parent.name[0]] = strings.Join(starValue, "/")
							parent = n
							i = i + 1 + len(segs[0])
							start = start + len(strings.Join(starValue, "/"))
							goto END
						} else {
							i = i + 1 + len(segs[0])
						}
					}
					matched.Params[parent.name[0]] = strings.Join(starValue, "/")
				} else {
					values := parent.regex.FindStringSubmatch(path[start:end])
					if len(values) != len(parent.name)+1 {
						return nil, fmt.Errorf("%s: Find wrong match %v, need names %v", path, values, parent.name)
					}
					for i, name := range parent.name {
						matched.Params[name] = values[i+1]
					}
				}
				break
			} else if parent.regex == nil {  
				matched.Params[parent.name[0]] = segment
			} else {
				values := parent.regex.FindStringSubmatch(segment)
				for i, name := range parent.name {
					matched.Params[name] = values[i+1]
				}
			}
		}
		start = i + 1
	END:
	}
	switch {
	case parent.endpoint:
		matched.Node = parent
	case parent.getChild("") != nil:
		matched.Path = path + "/"
	case len(parent.optionChildren) > 0:
		for _, child := range parent.optionChildren {
			matched.Node = child
			break
		}
	}
	return matched, nil
}
type Matched struct {
	Node *Node
	Params map[string]string
	Path string
}
type Node struct {
	name, allow                  []string
	pattern, segment             string
	endpoint, wildcard, optional bool
	parent                       *Node
	segChildren                  []*Node
	optionChildren               []*Node
	varyChildren                 []*Node
	children                     map[string]*Node
	handlers                     map[string]interface{}
	regex                        *regexp.Regexp
	namedRoutes                  map[string]*Node
}
func (n *Node) getSegments() string {
	segments := n.segment
	if n.parent != nil {
		segments = n.parent.getSegments() + "/" + segments
	}
	return segments
}
func (n *Node) getChild(key string) *Node {
	if strings.Contains(key, "::") {
		key = strings.Replace(key, "::", ":", -1)
	}
	if v, ok := n.children[key]; ok {
		return v
	}
	for _, c := range n.segChildren {
		if c.segment == key {
			return c
		}
	}
	for _, c := range n.optionChildren {
		if c.segment == key {
			return c
		}
	}
	for _, c := range n.varyChildren {
		if c.segment == key {
			return c
		}
	}
	return nil
}
func (n *Node) Name(name string) *Node {
	if n.getRootNode().namedRoutes == nil {
		n.getRootNode().namedRoutes = map[string]*Node{name: n}
	} else {
		if _, ok := n.getRootNode().namedRoutes[name]; ok {
			panic(fmt.Errorf("mux: route already has name %q, can't set", name))
		}
		n.getRootNode().namedRoutes[name] = n
	}
	return n
}
func (n *Node) GetName(name string) *Node {
	if n.getRootNode().namedRoutes != nil {
		return n.getRootNode().namedRoutes[name]
	}
	return nil
}
func (n *Node) getRootNode() *Node {
	if n.parent == nil {
		return n
	}
	return n.parent.getRootNode()
}
func (n *Node) BuildURL(pairs ...string) (*url.URL, error) {
	if len(pairs)%2 != 0 {
		return nil, fmt.Errorf("pairs expect even number key/val, but get %d", len(pairs))
	}
	params := make(map[string]string)
	var key string
	for k, v := range pairs {
		if k%2 == 0 {
			key = v
		} else {
			params[key] = v
		}
	}
	path, err := buildPath(strings.Split(n.pattern, "/"), params)
	if err != nil {
		return nil, err
	}
	return &url.URL{
		Path: path,
	}, nil
}
func buildPath(segments []string, params map[string]string) (string, error) {
	var results []string
	for {
		if len(segments) == 0 {
			break
		}
		segment := segments[0]
		segments = segments[1:]
		if strings.Contains(segment, "::") {
			results = append(results, strings.Replace(segment, "::", ":", -1))
		} else if segment == "*" {
			v, ok := params[":splat"]
			if !ok {
				return "", fmt.Errorf("* need to map to :splat, but the pairs doesn't exist the key :splat")
			}
			results = append(results, v)
		} else if segment == "*.*" {
			if p, ok := params[":path"]; !ok {
				return "", fmt.Errorf("*.* need to map to :path, but the pairs doesn't exist the key :path")
			} else if e, ok := params[":ext"]; !ok {
				return "", fmt.Errorf("*.* need to map to :ext, but the pairs doesn't exist the key :ext")
			} else {
				results = append(results, p+"."+e)
			}
		} else if optionalParamRegexp.MatchString(segment) {
			v, ok := params[segment[1:]]
			if !ok {
				continue
			}
			results = append(results, v)
		} else if paramRegexp.MatchString(segment) {
			v, ok := params[segment]
			if !ok {
				return "", fmt.Errorf("the pairs doesn't exist the key %s", segment)
			}
			results = append(results, v)
		} else if strings.ContainsAny(segment, ":") {
			names, regex, optional := regexpSegment(segment)
			rules := regex.String()
			for _, name := range names {
				if v, ok := params[name]; !ok {
					if optional {
						continue
					} else {
						return "", fmt.Errorf("the pairs doesn't exist the key %s for %s", name, segment)
					}
				} else {
					start := strings.IndexRune(rules, '(')
					end := strings.IndexByte(rules, ')')
					rules = rules[:start] + v + rules[end+1:]
				}
			}
			if rules != regex.String() {
				results = append(results, rules)
			}
		} else {
			results = append(results, segment)
		}
	}
	return strings.Join(results, "/"), nil
}
func (n *Node) Handle(method string, handler interface{}) {
	if n.GetHandler(method) != nil {
		panic(fmt.Errorf(`"%s" already defined`, n.getSegments()))
	}
	n.handlers[method] = handler
	n.allow = append(n.allow, method)
}
func (n *Node) GetHandler(method string) interface{} {
	return n.handlers[method]
}
func (n *Node) GetAllow() []string {
	return n.allow
}