111 lines
2.4 KiB
Go
111 lines
2.4 KiB
Go
package profanity
|
|
|
|
import (
|
|
"bufio"
|
|
"os"
|
|
"profanity/common"
|
|
"profanity/common/decanter"
|
|
"strings"
|
|
)
|
|
|
|
type Filter struct {
|
|
words map[string]string
|
|
Decanter decanter.Decanter
|
|
|
|
transforms []common.TransformFunc
|
|
}
|
|
|
|
func New() *Filter {
|
|
dec := decanter.NewDefaultDecanter()
|
|
return &Filter{
|
|
words: make(map[string]string, 3000),
|
|
Decanter: dec,
|
|
transforms: []common.TransformFunc{dec.DecantTransform},
|
|
}
|
|
}
|
|
|
|
//FilterWord
|
|
//curse is "" if bad == false, else curse is populated with the match
|
|
func (F *Filter) FilterWord(s string) (bad bool, curse string, form string) {
|
|
forms := common.FlattenTransformFunc(F.transforms)(s)
|
|
for _, form := range forms {
|
|
if curse, ok := F.words[form]; ok {
|
|
return true, curse, form
|
|
}
|
|
for _, v := range F.words {
|
|
if strings.Contains(form, v) {
|
|
return true, curse, form
|
|
}
|
|
}
|
|
}
|
|
return false, "", ""
|
|
}
|
|
|
|
func (F *Filter) CensorSentence(s string, replacer string) (censored string) {
|
|
return F.CensorSentenceN(s, replacer, 0)
|
|
}
|
|
|
|
func (F *Filter) CensorSentenceMany(s string, replacer string, widths ...uint8) (censored string) {
|
|
sentence := s
|
|
for _, width := range widths {
|
|
sentence = F.CensorSentenceN(sentence, replacer, width)
|
|
}
|
|
return sentence
|
|
}
|
|
|
|
func (F *Filter) CensorSentenceToN(s string, replacer string, maxwidth uint8) (censored string) {
|
|
sentence := s
|
|
for width := uint8(0); width < maxwidth; width++ {
|
|
sentence = F.CensorSentenceN(sentence, replacer, width)
|
|
}
|
|
return sentence
|
|
}
|
|
|
|
func (F *Filter) CensorSentenceN(s string, replacer string, width uint8) (censored string) {
|
|
sep := " "
|
|
sb := new(strings.Builder)
|
|
words := strings.Split(s, sep)
|
|
for idx := 0; idx < len(words); idx++ {
|
|
original := words[idx]
|
|
word := words[idx]
|
|
for i := 1; i <= int(width); i++ {
|
|
if len(words) > (idx + i) {
|
|
word = word + " " + words[idx+i]
|
|
}
|
|
}
|
|
if bad, _, form := F.FilterWord(word); bad {
|
|
idx = idx + int(width)
|
|
sb.WriteString(strings.Repeat(replacer, len(form)))
|
|
} else {
|
|
sb.WriteString(original)
|
|
}
|
|
sb.WriteString(sep)
|
|
}
|
|
return strings.TrimSpace(sb.String())
|
|
}
|
|
|
|
func (F *Filter) MustAddFile(file *os.File, err error) {
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
F.AddFile(file)
|
|
}
|
|
|
|
func (F *Filter) AddFile(file *os.File) {
|
|
scanner := bufio.NewScanner(file)
|
|
for scanner.Scan() {
|
|
txt := scanner.Text()
|
|
F.AddWord(txt)
|
|
}
|
|
}
|
|
|
|
func (F *Filter) AddWords(wx []string) {
|
|
for _, w := range wx {
|
|
F.AddWord(w)
|
|
}
|
|
}
|
|
|
|
func (F *Filter) AddWord(w string) {
|
|
F.words[w] = w
|
|
}
|