util.go 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. package main
  2. import (
  3. "regexp"
  4. "strconv"
  5. "strings"
  6. )
  7. var (
  8. regNumFloat, _ = regexp.Compile(`([1-9]\d*|0)(\.\d+)?`)
  9. regStrUnit, _ = regexp.Compile(`[元|万|亿]`)
  10. contentUnit, _ = regexp.Compile(`(万元|单位/万)`)
  11. numCapitals, _ = regexp.Compile(`([〇|零|点|壹|贰|叁|肆|伍|陆|柒|捌|玖|拾|百|佰|千|仟|万|亿|億|元|圆|角|分|整|正]{4,40})`)
  12. regStrChar = `[〇|零|点|壹|贰|叁|肆|伍|陆|柒|捌|玖|拾|百|佰|千|仟|万|亿|億|元|圆|角|分|整|正]`
  13. moneyRegChar, _ = regexp.Compile(regStrChar)
  14. regQianw, _ = regexp.Compile(`\d{1,2}千万`)
  15. cutAllSpace, _ = regexp.Compile(`\s*`)
  16. spaces = []string{"\u3000", "\u2003", "\u00a0", "\t", "\r", "\n"}
  17. moneyChar = map[string]interface{}{ //"〇": "0", "零": "0",
  18. "一": float64(1), "壹": float64(1), "二": float64(2), "贰": float64(2), "三": float64(3), "叁": float64(3), "四": float64(4), "肆": float64(4), "五": float64(5), "伍": float64(5),
  19. "六": float64(6), "陆": float64(6), "七": float64(7), "柒": float64(7), "八": float64(8), "捌": float64(8), "九": float64(9), "玖": float64(9), "十": float64(10), "拾": float64(10),
  20. "百": float64(100), "佰": float64(100), "千": float64(1000), "仟": float64(1000), "万": float64(10000), "亿": float64(100000000), "億": float64(100000000),
  21. "零": float64(0), "点": ".", "角": float64(0.1), "分": float64(0.01),
  22. }
  23. moneyUnit = map[string]float64{
  24. "元": float64(1), "万": float64(10000), "亿": float64(100000000), "億": float64(100000000), //单位
  25. }
  26. )
  27. var currencyItem = map[string]string{
  28. "人民币": "人民币",
  29. "rmb": "人民币",
  30. "RMB": "人民币",
  31. "$": "美元",
  32. "$": "美元",
  33. "美元": "美元",
  34. "港元": "港币",
  35. "港币": "港币",
  36. "澳币": "澳币",
  37. "澳元": "澳币",
  38. }
  39. // 获取币种
  40. func GetCurrency(text string) (currency string) {
  41. if text == "" {
  42. return
  43. }
  44. currency = "人民币"
  45. for k, v := range currencyItem {
  46. if strings.Contains(text, k) {
  47. currency = v
  48. return
  49. }
  50. }
  51. return
  52. }
  53. // 金额转换
  54. func ObjToMoney(text string) float64 {
  55. isfindUnit := true
  56. ret := capitalMoney(text)
  57. if ret < float64(10000) || ret > float64(50000000000) {
  58. ret2, b := numMoney(text)
  59. isfindUnit = b
  60. if ret2 > ret {
  61. ret = ret2
  62. }
  63. }
  64. f, _ := strconv.ParseFloat(strconv.FormatFloat(ret, 'f', 4, 64), 64)
  65. // if f < 1 {
  66. // f = 0
  67. // }
  68. //如果金额小于50,全文检索单位:万
  69. if f < 50 && f > 0 && isfindUnit {
  70. rep := contentUnit.FindAllStringIndex(text, -1)
  71. if len(rep) > 0 {
  72. f = f * 10000
  73. }
  74. }
  75. return f
  76. }
  77. func capitalMoney(text string) float64 {
  78. nodes := []float64{}
  79. node := float64(0)
  80. tmp := float64(0)
  81. decimals := 0.0
  82. ishaspoint := false //是否含小数点
  83. fnum := float64(0)
  84. end := false
  85. //str := fmt.Sprint(data[0])
  86. //提取第一个大写信息
  87. strmatch := numCapitals.FindAllStringSubmatch(text, -1)
  88. if len(strmatch) > 0 {
  89. text = strmatch[0][0]
  90. }
  91. suffixUnit := float64(1)
  92. if strings.HasSuffix(text, "万") || strings.HasSuffix(text, "万元") || strings.HasSuffix(text, "万元整") {
  93. index := strings.LastIndex(text, "万")
  94. text = text[0:index]
  95. suffixUnit = float64(10000)
  96. }
  97. moneyRegChar.ReplaceAllStringFunc(text, func(key string) string {
  98. if key == "元" || key == "圆" || key == "点" {
  99. ishaspoint = true
  100. }
  101. if v, ok := moneyChar[key].(float64); ok && !end {
  102. if ishaspoint && v > 10 { //排除后面有其他的单位
  103. return ""
  104. }
  105. //fmt.Println(key, v, fnum)
  106. if v < 10 && v >= 0 {
  107. if ishaspoint { //小数部分
  108. if v >= 1 {
  109. fnum = v
  110. } else if v < 1 && v > 0 {
  111. decimals += fnum * v
  112. }
  113. } else {
  114. if tmp != float64(0) {
  115. node += tmp
  116. }
  117. tmp = float64(v)
  118. }
  119. } else if v == 10000 || v == 100000000 { //单位万、亿
  120. if tmp != float64(0) {
  121. node += tmp
  122. tmp = float64(0)
  123. }
  124. nodes = append(nodes, node*float64(v))
  125. node = float64(0)
  126. } else {
  127. if v == 10 && tmp == 0 {
  128. tmp = 1
  129. }
  130. tmp = tmp * float64(v)
  131. node += tmp
  132. tmp = float64(0)
  133. }
  134. }
  135. if key == "整" || key == "正" || key == "分" {
  136. end = true
  137. }
  138. return ""
  139. })
  140. nodes = append(nodes, node, tmp)
  141. ret := float64(0)
  142. for _, v := range nodes {
  143. ret += v
  144. }
  145. return (ret + decimals) * suffixUnit
  146. }
  147. // 数字金额转换
  148. func numMoney(text string) (moneyFloat float64, flag bool) {
  149. //tmp := fmt.Sprintf("%f", data[0])
  150. repUnit := float64(1)
  151. if regQianw.MatchString(text) {
  152. text = strings.Replace(text, "千万", "万", -1)
  153. repUnit = float64(1000)
  154. }
  155. text = replaceSymbol(text, []string{",", ",", "(", ")", "(", ")", ":", "\n"})
  156. text = replaceString(text, []string{"万元", "亿元", "."}, []string{"万", "亿", "."})
  157. text = CutAllSpace(text)
  158. rets := regNumFloat.FindAllString(text, -1)
  159. fnums := []float64{}
  160. unitstrs := []string{}
  161. if len(rets) > 0 {
  162. pindex := 0 //单位前置
  163. for k, v := range rets {
  164. f, err := strconv.ParseFloat(v, 64)
  165. if err == nil {
  166. fnums = append(fnums, f)
  167. index := strings.Index(text, v)
  168. //单位后置
  169. start := index + len(v)
  170. end := start + 3
  171. //log.Println("vvv", tmp, v, pindex, index, start)
  172. if k > 0 {
  173. if start >= pindex+3 {
  174. pstart := pindex + 3
  175. if pstart >= index {
  176. pstart = index
  177. }
  178. if len(text) > end {
  179. unitstrs = append(unitstrs, text[pstart:index]+text[start:end])
  180. } else {
  181. unitstrs = append(unitstrs, text[pstart:index]+text[start:])
  182. }
  183. } else {
  184. if len(text) > end {
  185. unitstrs = append(unitstrs, text[start:end])
  186. } else {
  187. unitstrs = append(unitstrs, text[start:])
  188. }
  189. }
  190. } else {
  191. if len(text) > end {
  192. if index-3 >= 0 {
  193. unitstrs = append(unitstrs, text[index-3:index]+text[start:end])
  194. } else {
  195. unitstrs = append(unitstrs, text[start:end])
  196. }
  197. } else {
  198. if index-3 >= 0 {
  199. unitstrs = append(unitstrs, text[index-3:index]+text[start:])
  200. } else {
  201. unitstrs = append(unitstrs, text[start:])
  202. }
  203. }
  204. }
  205. pindex = start
  206. }
  207. }
  208. }
  209. //log.Println("unitstrs", fnums, unitstrs)
  210. unit := float64(0)
  211. fnum := float64(0)
  212. for k, v := range fnums {
  213. fnum = v
  214. units := regStrUnit.FindAllString(unitstrs[k], -1)
  215. for _, v := range units {
  216. if moneyUnit[v] != 0 {
  217. unit = moneyUnit[v]
  218. break
  219. }
  220. }
  221. if unit != float64(0) { //取第一个
  222. break
  223. }
  224. }
  225. fnum = fnum * repUnit
  226. if unit == float64(0) {
  227. moneyFloat = fnum
  228. } else {
  229. moneyFloat = fnum * unit
  230. }
  231. if unit == 10000 {
  232. flag = false
  233. } else {
  234. flag = true
  235. }
  236. return
  237. }
  238. // 清理所有空白符
  239. func CutAllSpace(text string) string {
  240. tmp := cutAllSpace.ReplaceAllString(text, "")
  241. tmp = replaceSymbol(tmp, spaces)
  242. return tmp
  243. }
  244. // 符号替换
  245. func replaceString(con string, ret, rep []string) string {
  246. for k, v := range ret {
  247. if len(rep) > k {
  248. con = strings.Replace(con, v, rep[k], -1)
  249. }
  250. }
  251. return con
  252. }
  253. // 过滤符号
  254. func replaceSymbol(con string, rep []string) string {
  255. for _, v := range rep {
  256. con = strings.Replace(con, v, "", -1)
  257. }
  258. return con
  259. }
  260. // IsInSlice 判断目标字符串是否是在切片中
  261. func IsInSlice(slice []string, s string) bool {
  262. if len(slice) == 0 {
  263. return false
  264. }
  265. isIn := false
  266. for _, f := range slice {
  267. if f == s {
  268. isIn = true
  269. break
  270. }
  271. }
  272. return isIn
  273. }