tonumber.go 7.4 KB

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