package service import ( "bufio" "fmt" "os" "regexp" "strings" ) // RunTest 运行测试,检测模板 // 标签对{{~}}开头 ,{{end}}结尾 // - {{for .item in .list}} {{end}} // - {{if .bool}}~{{end}} // - {{if .bool}}~{{else}}~{{end}} // - {{if .bool}}~{{elseif}}~{{else}}~{{end}} // // 单标签 // - {{.item}} // 解析模板 func RunTest() { tmpl := ReadFileToString() //compileRegex := regexp.MustCompile("{{2} *(for *\\w+ +in +\\.\\w+)|(if +\\.\\w+)|(else)|(else +if +\\.\\w+) *}{2}") // 正则表达式的分组,以括号()表示,每一对括号就是我们匹配到的一个文本,可以把他们提取出来。 //matchArr := compileRegex.FindStringSubmatch(tmpl) // FindStringSubmatch 方法是提取出匹配的字符串,然后通过[]string返回。我们可以看到,第1个匹配到的是这个字符串本身,从第2个开始,才是我们想要的字符串。 //if len(matchArr) > 0 { // fmt.Println("提取字符串内容:", matchArr[len(matchArr)-1]) // 输出:蜜桃乌龙茶 //} var err error AllTagReg, err = regexp.Compile("^{{2} *(for *\\w+ +in +\\.\\w+)|(if +\\.\\w+)|(else)|(else +if +\\.\\w+) *}{2}$") if err != nil { panic(err) } ForReg, err = regexp.Compile("^{{2} *for *\\w+ +in +\\.\\w+ *}{2}$") if err != nil { panic(err) } IfReg, err = regexp.Compile("^{{2} *if +\\.\\w+ *}{2}$") if err != nil { panic(err) } IfElseReg, err = regexp.Compile("^{{2} *else +if +\\.\\w+ *}{2}$") if err != nil { panic(err) } ElseReg, err = regexp.Compile("^{{2} *else *}{2}$") if err != nil { panic(err) } End, err = regexp.Compile("^{{2} *end *}{2}$") if err != nil { panic(err) } Item, err = regexp.Compile("^{{2} *\\.\\w+ *}{2}$") template, index, err := AnalysisTemplate(tmpl, 0) if err != nil { fmt.Println(err) } fmt.Println(template, index) } var AllTagReg *regexp.Regexp var ForReg *regexp.Regexp var IfReg *regexp.Regexp var IfElseReg *regexp.Regexp var ElseReg *regexp.Regexp var End *regexp.Regexp var Item *regexp.Regexp type Template struct { Tag string //标签 TagType string //标签类型 for if Content string // SubTemplate []Template } func (t Template) String() string { return fmt.Sprintf("Tag:%s,TagType:%s,Content:%s,SubTemplate:%s", t.Tag, t.TagType, t.Content, t.SubTemplate) } // AnalysisTemplate func AnalysisTemplate(tmpl string, startIndex int) (Template, int, error) { template := Template{} index := IndexOf(tmpl, "{{", startIndex) if index == -1 { //完美 return template, -1, nil } endIndex := IndexOf(tmpl, "}}", index+1) if endIndex == -1 { return template, -1, nil } str := tmpl[index : endIndex+2] //正则判断 if AllTagReg.MatchString(str) { compileRegex := regexp.MustCompile("\\{\\{ *(for|if|elseif|else|end) +.* *}}") matchArr := compileRegex.FindStringSubmatch(str) template.TagType = matchArr[1] //匹配到 template.Tag = str template.Content = tmpl[index+2 : endIndex] return template, endIndex + 2, nil } return Template{}, index, nil } func IndexOf(s, subString string, startIndex int) int { str := s[startIndex:] index := strings.Index(str, subString) if index == -1 { return -1 } return index + startIndex } func ReadFileToString() string { file, err := os.OpenFile("./service/struct.go.template", os.O_CREATE|os.O_RDWR, 0666) if err != nil { panic(err) } defer file.Close() reader := bufio.NewReader(file) var bytes = make([]byte, 1024) for { n, err := reader.Read(bytes) if err != nil { panic(err) } bytes = append(bytes, bytes[:n]...) if n < 1024 { break } } return string(bytes) }