波斯汪
使用模板解析器的困难方法^^package mainimport ( "fmt" "strings" "text/template/parse")func main() { input := "{{number1}} + {{number2}} > {{number3}}" out := parseit(input) fmt.Printf("%#v\n", out)}func parseit(input string) (out []string) { input = strings.Replace(input, "{{", "{{.", -1) // Force func calls to become variables. tree, err := parse.Parse("", input, "{{", "}}") if err != nil { panic(err) } visit(tree[""].Root, func(n parse.Node) bool { x, ok := n.(*parse.FieldNode) if ok { out = append(out, strings.Join(x.Ident, ".")) } return true }) return}func visit(n parse.Node, fn func(parse.Node) bool) bool { if n == nil { return true } if !fn(n) { return false } if l, ok := n.(*parse.ListNode); ok { for _, nn := range l.Nodes { if !visit(nn, fn) { continue } } } if l, ok := n.(*parse.RangeNode); ok { if !visit(l.BranchNode.Pipe, fn) { return false } if l.BranchNode.List != nil { if !visit(l.BranchNode.List, fn) { return false } } if l.BranchNode.ElseList != nil { if !visit(l.BranchNode.ElseList, fn) { return false } } } if l, ok := n.(*parse.ActionNode); ok { for _, c := range l.Pipe.Decl { if !visit(c, fn) { continue } } for _, c := range l.Pipe.Cmds { if !visit(c, fn) { continue } } } if l, ok := n.(*parse.CommandNode); ok { for _, a := range l.Args { if !visit(a, fn) { continue } } } if l, ok := n.(*parse.PipeNode); ok { for _, a := range l.Decl { if !visit(a, fn) { continue } } for _, a := range l.Cmds { if !visit(a, fn) { continue } } } return true}如果发生这种情况,您确实在操作模板字符串,但由于函数调用而未能执行此操作,并且您不想执行此操作input = strings.Replace(input, "{{", "{{.", -1) // Force func calls to become variables.您始终可以使用类似于var reMissingIdent = regexp.MustCompile(`template: :[0-9]+: function "([^"]+)" not defined`)func ParseTextTemplateAnyway(s string) (*texttemplate.Template, texttemplate.FuncMap, error) { fn := texttemplate.FuncMap{} for { t, err := texttemplate.New("").Funcs(fn).Parse(s) if err == nil { return t, fn, err } s := err.Error() res := reMissingIdent.FindAllStringSubmatch(s, -1) if len(res) > 0 { fn[res[0][1]] = func(s ...interface{}) string { return "" } } else { return t, fn, err } } // return nil, nil}