package danmaku import ( "git.noahlan.cn/northlan/ntools-go/stringn/ac" "strings" ) type ( CMD struct { IsCMD bool // 是否CMD Arr []string // 具体CMD []string } Parser struct { trie *ac.Trie allKeyArr []string keywordMap map[string]struct{} } ParserBuilder struct { } ) func NewCMDParser(keys []string) *Parser { p := &Parser{ keywordMap: make(map[string]struct{}), allKeyArr: make([]string, len(keys)), } for _, keyword := range keys { p.keywordMap[keyword] = struct{}{} p.allKeyArr = append(p.allKeyArr, keyword) } p.trie = ac.NewTrieBuilder().AddStrings(p.allKeyArr).Build() return p } func (p *Parser) ParseTest(content string) { p.trie.MatchString(content) } func (p *Parser) Parse(content string) *CMD { // 移除多余空格,小写 tmpContent := strings.ToLower(strings.TrimSpace(content)) matches := p.trie.MatchString(tmpContent) allKeyLen := 0 matchedKeyMap := make(map[string]struct{}) for _, match := range matches { tmp := p.allKeyArr[match.Pattern()] matchedKeyMap[tmp] = struct{}{} allKeyLen += len(tmp) } isCMD := len(tmpContent) <= allKeyLen // 避免同类型指令重复 arrMap := make(map[rune]struct{}) var matchedCmdArr []string if isCMD { matchedCmdArr = make([]string, 0, len(matchedKeyMap)) for s := range matchedKeyMap { sRune := []rune(s) if _, ok := arrMap[sRune[0]]; !ok { arrMap[sRune[0]] = struct{}{} matchedCmdArr = append(matchedCmdArr, s) } } } return &CMD{ IsCMD: len(tmpContent) <= allKeyLen, Arr: matchedCmdArr, } }