gitee.com/h79/goutils@v1.22.10/sensitive/regexp.go (about)

     1  package sensitive
     2  
     3  import (
     4  	"gitee.com/h79/goutils/common/algorithm"
     5  	"gitee.com/h79/goutils/common/trie"
     6  	"regexp"
     7  	"sync"
     8  )
     9  
    10  type Regexp struct {
    11  	locker sync.Mutex
    12  	items  map[uint64]*regexp.Regexp
    13  }
    14  
    15  func NewRegexp() *Regexp {
    16  	return &Regexp{items: make(map[uint64]*regexp.Regexp)}
    17  }
    18  
    19  func (r *Regexp) Add(reg string) (*regexp.Regexp, error) {
    20  	hashId := algorithm.FnvSum64(reg)
    21  	r.locker.Lock()
    22  	defer func() {
    23  		r.locker.Unlock()
    24  	}()
    25  	if it, ok := r.items[hashId]; ok {
    26  		return it, nil
    27  	}
    28  	it, err := regexp.Compile(reg)
    29  	if err != nil {
    30  		return nil, err
    31  	}
    32  	r.items[hashId] = it
    33  	return it, nil
    34  }
    35  
    36  func (r *Regexp) Del(reg string) {
    37  	hashId := algorithm.FnvSum64(reg)
    38  	r.locker.Lock()
    39  	defer r.locker.Unlock()
    40  	delete(r.items, hashId)
    41  }
    42  
    43  func (r *Regexp) Filter(text string) string {
    44  	return r.Replace(text, "")
    45  }
    46  
    47  func (r *Regexp) Replace(text string, repl string) string {
    48  	regs := r.find(text)
    49  	if len(regs) <= 0 {
    50  		return text
    51  	}
    52  	for _, reg := range regs {
    53  		text = reg.ReplaceAllString(text, repl)
    54  	}
    55  	return text
    56  }
    57  
    58  // FindIn 检测敏感词
    59  func (r *Regexp) FindIn(text string) (bool, string) {
    60  	regs := r.find(text)
    61  	if len(regs) <= 0 {
    62  		return false, ""
    63  	}
    64  	var in []string
    65  	for _, reg := range regs {
    66  		in = append(in, reg.FindString(text))
    67  	}
    68  	return true, in[0]
    69  }
    70  
    71  // FindAll 找到所有匹配词
    72  func (r *Regexp) FindAll(text string) []*trie.Group {
    73  	r.locker.Lock()
    74  	defer r.locker.Unlock()
    75  	var (
    76  		group []*trie.Group
    77  		ff    [][]int
    78  	)
    79  	for _, reg := range r.items {
    80  		ff = reg.FindAllStringIndex(text, -1)
    81  		if len(ff) <= 0 {
    82  			continue
    83  		}
    84  		for i := range ff {
    85  			if len(ff[i]) < 2 {
    86  				continue
    87  			}
    88  			gr := &trie.Group{Text: text[ff[i][0]:ff[i][1]], Index: ff[i][0]}
    89  			group = append(group, gr)
    90  		}
    91  	}
    92  	return group
    93  }
    94  
    95  func (r *Regexp) Validate(text string) (bool, string) {
    96  	validated, first := r.FindIn(text)
    97  	return !validated, first
    98  }
    99  
   100  func (r *Regexp) find(text string) []*regexp.Regexp {
   101  	r.locker.Lock()
   102  	defer r.locker.Unlock()
   103  	var regs []*regexp.Regexp
   104  	for _, v := range r.items {
   105  		if v.MatchString(text) {
   106  			regs = append(regs, v)
   107  		}
   108  	}
   109  	return regs
   110  }