You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
68 lines
1.4 KiB
Go
68 lines
1.4 KiB
Go
3 years ago
|
package danmaku
|
||
|
|
||
|
import (
|
||
|
"git.noahlan.cn/northlan/ntools-go/stringn/ac"
|
||
|
)
|
||
|
|
||
|
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 {
|
||
|
matches := p.trie.MatchString(content)
|
||
|
|
||
|
allKeyLen := 0
|
||
|
matchedKeyMap := make(map[string]struct{})
|
||
|
for _, match := range matches {
|
||
|
tmp := p.allKeyArr[match.Pattern()]
|
||
|
matchedKeyMap[tmp] = struct{}{}
|
||
|
allKeyLen += len(tmp)
|
||
|
}
|
||
|
isCMD := len(content) <= 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(content) <= allKeyLen,
|
||
|
Arr: matchedCmdArr,
|
||
|
}
|
||
|
}
|