tonumber.go 8.1 KB

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