util.go 6.7 KB

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