util.go 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. package main
  2. import (
  3. util "jygit.jydev.jianyu360.cn/data_processing/common_utils"
  4. "jygit.jydev.jianyu360.cn/data_processing/common_utils/mongodb"
  5. "mobile_tag/oss"
  6. "regexp"
  7. "sort"
  8. "strings"
  9. )
  10. type TagMatching struct {
  11. tagName string //标签名称
  12. tagCode string //标签值(保存)
  13. matchField []string //关键词匹配字段,title,detail
  14. matchKey string //匹配的词语,多个使用逗号连接,"部队,国防,军事,军用"
  15. matchKeyReg []*RegexpInfo //关键词的正则
  16. addField []string //附加词匹配字段
  17. addKey string //附件词匹配关键词
  18. addKeyReg []*RegexpInfo //附加次的正则
  19. excludeField []string //排除词匹配字段
  20. excludeKey string //排除词匹配词
  21. excludeKeyReg []*RegexpInfo //排除词正则
  22. //clearKey []string //清理词匹配字段跟关键词一样
  23. }
  24. type RegexpInfo struct {
  25. keyStr string
  26. regs *regexp.Regexp
  27. }
  28. // GetRegex 根据关键词或者对应正则
  29. func GetRegex(key string) []*RegexpInfo {
  30. var infos []*RegexpInfo
  31. for _, s := range strings.Split(key, ",") {
  32. if strings.Contains(s, "&&") || strings.Contains(s, "&!") {
  33. info := &RegexpInfo{
  34. keyStr: s,
  35. regs: nil,
  36. }
  37. infos = append(infos, info)
  38. } else {
  39. info := &RegexpInfo{
  40. keyStr: s,
  41. regs: regexp.MustCompile(".*(?i)" + s + ".*"),
  42. }
  43. infos = append(infos, info)
  44. }
  45. }
  46. return infos
  47. }
  48. // TaskTags 根据数据和正则规则,验证数据标签
  49. func TaskTags(tmp map[string]interface{}, regs []TagMatching) (tags []string, keyWord, addWord string) {
  50. // 在匹配字段里,比如标题满足了关键词,详情满足附加词,关键词的匹配字段含有标题,附加词的匹配字段含有详情;就符合条件
  51. Loop:
  52. for _, v := range regs {
  53. keyR := false // 关键词匹配结果
  54. addR := false //附加次匹配结果
  55. // 1.排除词
  56. if len(v.excludeField) > 0 && len(v.excludeKeyReg) > 0 {
  57. // 遍历排除词对应的tmp字段信息
  58. for _, f := range v.excludeField {
  59. if val := util.ObjToString(tmp[f]); val != "" {
  60. if rs, _ := getRegsResult(val, v.excludeKeyReg); rs {
  61. //有排除词,直接判断下一个规则
  62. continue Loop
  63. }
  64. }
  65. }
  66. }
  67. // 清理词;目的把 类似 fuck的单词替换为空字符串
  68. //if len(v.clearKey) > 0 && len(v.matchField) > 0 {
  69. // for _, s := range v.clearKey {
  70. // for _, f := range v.matchField {
  71. // if val := util.ObjToString(tmp[f]); val != "" {
  72. // tmp[f] = strings.ReplaceAll(val, s, "")
  73. // }
  74. // }
  75. // }
  76. //}
  77. // 关键词
  78. if len(v.matchField) > 0 && len(v.matchKeyReg) > 0 {
  79. for _, f := range v.matchField {
  80. if val := util.ObjToString(tmp[f]); val != "" {
  81. if rs, da := getRegsResult(val, v.matchKeyReg); rs {
  82. keyR = true
  83. keyWord = da
  84. //log.Print("key", da)
  85. break
  86. }
  87. }
  88. }
  89. }
  90. // 附加词
  91. if len(v.addField) > 0 && len(v.addKeyReg) > 0 && keyR {
  92. for _, f := range v.addField {
  93. if val := util.ObjToString(tmp[f]); val != "" {
  94. if rs, da := getRegsResult(val, v.addKeyReg); rs {
  95. addR = true
  96. addWord = da
  97. //log.Println("add", da)
  98. break
  99. }
  100. }
  101. }
  102. } else {
  103. addR = true
  104. }
  105. // 满足 关键词和附加词条件
  106. if keyR && addR {
  107. // 去重相同标签
  108. if !IsInStringArray(v.tagName, tags) {
  109. tags = append(tags, v.tagName)
  110. }
  111. }
  112. }
  113. return
  114. }
  115. // getRegsResult 验证数据是否符合数组正则
  116. func getRegsResult(data string, regs []*RegexpInfo) (res bool, a string) {
  117. for _, e1 := range regs {
  118. if e1.regs != nil && e1.regs.MatchString(data) {
  119. return true, e1.regs.String()
  120. } else {
  121. // && 特殊处理
  122. if strings.Contains(e1.keyStr, "&&") {
  123. flag := true
  124. for _, s := range strings.Split(e1.keyStr, "&&") {
  125. if !strings.Contains(data, s) {
  126. flag = false
  127. break
  128. }
  129. }
  130. if flag {
  131. return true, e1.keyStr
  132. }
  133. }
  134. // 前面是必须有的关键词&!,后面是不能有的关键词;比如 军队&!点军队,
  135. if strings.Contains(e1.keyStr, "&!") {
  136. keys := strings.Split(e1.keyStr, "&!")
  137. if strings.Contains(data, keys[0]) && !strings.Contains(data, keys[1]) {
  138. return true, e1.keyStr
  139. }
  140. }
  141. }
  142. }
  143. return false, ""
  144. }
  145. // IsInStringArray 判断数组中是否存在字符串
  146. func IsInStringArray(str string, arr []string) bool {
  147. // 先对字符串数组进行排序
  148. sort.Strings(arr)
  149. // 使用二分查找算法查找字符串
  150. pos := sort.SearchStrings(arr, str)
  151. // 如果找到了则返回 true,否则返回 false
  152. return pos < len(arr) && arr[pos] == str
  153. }
  154. // getFileText 获取附件内容
  155. func getFileText(tmp map[string]interface{}) (filetext string) {
  156. if attchMap, ok := tmp["attach_text"].(map[string]interface{}); attchMap != nil && ok {
  157. for _, tmpData1 := range attchMap {
  158. if tmpData2, ok := tmpData1.(map[string]interface{}); tmpData2 != nil && ok {
  159. for _, result := range tmpData2 {
  160. if resultMap, ok := result.(map[string]interface{}); resultMap != nil && ok {
  161. if attach_url := util.ObjToString(resultMap["attach_url"]); attach_url != "" {
  162. bs := oss.OssGetObject(attach_url, mongodb.BsonIdToSId(tmp["_id"])) //oss读数据
  163. filetext += bs
  164. }
  165. }
  166. }
  167. }
  168. }
  169. }
  170. return
  171. }