|
@@ -0,0 +1,90 @@
|
|
|
+package fsw
|
|
|
+
|
|
|
+//敏感词过滤,扩展,类似查字典
|
|
|
+type Fsw struct {
|
|
|
+ IsStart bool
|
|
|
+ IsEnd bool
|
|
|
+ Char string //字符
|
|
|
+ Link map[string]*Fsw //下级对象
|
|
|
+}
|
|
|
+
|
|
|
+//
|
|
|
+type FswScan struct {
|
|
|
+ FswDictionary map[string]*Fsw //
|
|
|
+}
|
|
|
+
|
|
|
+//
|
|
|
+func NewFswScan() *FswScan {
|
|
|
+ return &FswScan{
|
|
|
+ FswDictionary: make(map[string]*Fsw),
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+//追加
|
|
|
+func (fsw *FswScan) AddWord(word string) {
|
|
|
+ var cfsw *Fsw
|
|
|
+ rs := []rune(word)
|
|
|
+ for i, wv := range rs {
|
|
|
+ kc := string(wv)
|
|
|
+ if i == 0 { //初始化
|
|
|
+ if v, ok := fsw.FswDictionary[kc]; ok {
|
|
|
+ cfsw = v
|
|
|
+ } else {
|
|
|
+ cfsw = &Fsw{
|
|
|
+ Char: kc,
|
|
|
+ IsStart: true,
|
|
|
+ Link: make(map[string]*Fsw),
|
|
|
+ }
|
|
|
+ fsw.FswDictionary[kc] = cfsw
|
|
|
+ }
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ //查询
|
|
|
+ if v, ok := (*cfsw).Link[kc]; ok {
|
|
|
+ cfsw = v
|
|
|
+ } else {
|
|
|
+ tmp := &Fsw{
|
|
|
+ Char: kc,
|
|
|
+ IsStart: true,
|
|
|
+ Link: make(map[string]*Fsw),
|
|
|
+ }
|
|
|
+ (*cfsw).Link[kc] = tmp
|
|
|
+ cfsw = tmp
|
|
|
+ }
|
|
|
+ //判断结束
|
|
|
+ }
|
|
|
+ (*cfsw).IsEnd = true
|
|
|
+}
|
|
|
+
|
|
|
+//
|
|
|
+func (fsw *FswScan) AddWords(words []string) {
|
|
|
+ for _, v := range words {
|
|
|
+ fsw.AddWord(v)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/*按字典查找
|
|
|
+匹配模式:最大匹配,最小匹配,
|
|
|
+目前是最小匹配
|
|
|
+*/
|
|
|
+func (fsw *FswScan) Filter(src string) (string, bool) {
|
|
|
+ rs := []rune(src)
|
|
|
+ for i := 0; i < len(rs); i++ {
|
|
|
+ char := string(rs[i])
|
|
|
+ if f, ok := fsw.FswDictionary[char]; ok { //某1个字匹配上了
|
|
|
+ for j := i + 1; j < len(rs); j++ {
|
|
|
+ char = string(rs[j])
|
|
|
+ if v, ok := f.Link[char]; ok {
|
|
|
+ f = v
|
|
|
+ if v.IsEnd { //找到了
|
|
|
+ return string(rs[i : j+1]), true
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ return "", false
|
|
|
+}
|