// tonumber package main import ( "fmt" "regexp" "strconv" "strings" ) var contentUnit *regexp.Regexp //全文检索单位:万元 var regOperator *regexp.Regexp //运算符号 var regNumFloat *regexp.Regexp //提取整数或浮点数 var moneyRegChar *regexp.Regexp //提取中文数字 var regStrUnit *regexp.Regexp //提取单位 var moneyChar = map[string]interface{}{ //"〇": "0", "零": "0", "一": float64(1), "壹": float64(1), "二": float64(2), "贰": float64(2), "三": float64(3), "叁": float64(3), "四": float64(4), "肆": float64(4), "五": float64(5), "伍": float64(5), "六": float64(6), "陆": float64(6), "七": float64(7), "柒": float64(7), "八": float64(8), "捌": float64(8), "九": float64(9), "玖": float64(9), "十": float64(10), "拾": float64(10), "百": float64(100), "佰": float64(100), "千": float64(1000), "仟": float64(1000), "万": float64(10000), "亿": float64(100000000), "億": float64(100000000), "零": float64(0), "点": ".", "角": float64(0.1), "分": float64(0.01), } var moneyUnit = map[string]float64{ "元": float64(1), "万": float64(10000), "亿": float64(100000000), "億": float64(100000000), //单位 } var spaces = []string{"\u3000", "\u2003", "\u00a0"} var cutAllSpace = regexp.MustCompile(`\s*`) func init() { regOperator, _ = regexp.Compile(`[*|+|)*)]`) regNumFloat, _ = regexp.Compile(`([1-9]\d*|0)(\.\d+)?`) regStrUnit, _ = regexp.Compile(`[元|万|亿]`) regStrChar := `[〇|零|点|.|.|壹|贰|叁|肆|伍|陆|柒|捌|玖|拾|百|佰|千|仟|万|亿|億|元|圆|角|分|整|正]` moneyRegChar, _ = regexp.Compile(regStrChar) contentUnit, _ = regexp.Compile(`(万元|单位/万)`) } //转int func ObjToInt(data []interface{}) []interface{} { tmp, err := strconv.Atoi(fmt.Sprint(data[0])) if err != nil { data[0] = 0 return data } else { data[0] = tmp return data } } //转float,精度小数点4位 func ObjToFloat(data []interface{}) []interface{} { tmp, err := strconv.ParseFloat(fmt.Sprint(data[0]), 64) if err != nil { return []interface{}{float64(0), data[1]} } else { tmp, err = strconv.ParseFloat(strconv.FormatFloat(tmp, 'f', 4, 64), 64) if err != nil { return []interface{}{float64(0), data[1]} } else { return []interface{}{tmp, data[1]} } } } //金额转换 func ObjToMoney(data []interface{}) []interface{} { isfindUnit := true ret := capitalMoney(data)[0] if ret.(float64) < float64(10000) || ret.(float64) > float64(50000000000) { ret2, b := numMoney(data) isfindUnit = b if ret2[0].(float64) > ret.(float64) { ret = ret2[0] } } f, _ := strconv.ParseFloat(strconv.FormatFloat(ret.(float64), 'f', 4, 64), 64) if f < 1 { f = 0 } //若果金额小于50,全文检索单位:万 if f < 50 && f > 0 && isfindUnit { rep := contentUnit.FindAllStringIndex(fmt.Sprint(data[1]), -1) if len(rep) > 0 { f = f * 10000 } } data[0] = f return data } //清理所有空白符 func CutAllSpace(data []interface{}) []interface{} { tmp := cutAllSpace.ReplaceAllString(fmt.Sprint(data[0]), "") tmp = replaceSymbol(tmp, spaces) data[0] = tmp return data } //数字金额转换 func numMoney(data []interface{}) ([]interface{}, bool) { tmp := fmt.Sprint(data[0]) tmp = replaceSymbol(tmp, []string{",", ",", "(", ")", "(", ")", ":", "\n"}) tmp = replaceString(tmp, []string{"万元", "亿元", "."}, []string{"万", "亿", "."}) tmp = fmt.Sprint(CutAllSpace([]interface{}{tmp, data[1]})[0]) rets := regNumFloat.FindAllString(tmp, -1) fnums := []float64{} unitstrs := []string{} if len(rets) > 0 { pindex := 0 //单位前置 for k, v := range rets { f, err := strconv.ParseFloat(v, 64) if err == nil { fnums = append(fnums, f) index := strings.Index(tmp, v) //单位后置 start := index + len(v) end := start + 3 //log.Println("vvv", tmp, v, pindex, index, start) if k > 0 { if start >= pindex+3 { pstart := pindex + 3 if pstart >= index { pstart = index } if len(tmp) > end { unitstrs = append(unitstrs, tmp[pstart:index]+tmp[start:end]) } else { unitstrs = append(unitstrs, tmp[pstart:index]+tmp[start:]) } } else { if len(tmp) > end { unitstrs = append(unitstrs, tmp[start:end]) } else { unitstrs = append(unitstrs, tmp[start:]) } } } else { if len(tmp) > end { if index-3 >= 0 { unitstrs = append(unitstrs, tmp[index-3:index]+tmp[start:end]) } else { unitstrs = append(unitstrs, tmp[start:end]) } } else { if index-3 >= 0 { unitstrs = append(unitstrs, tmp[index-3:index]+tmp[start:]) } else { unitstrs = append(unitstrs, tmp[start:]) } } } pindex = start } } } //log.Println("unitstrs", fnums, unitstrs) unit := float64(0) fnum := float64(0) for k, v := range fnums { fnum = v units := regStrUnit.FindAllString(unitstrs[k], -1) for _, v := range units { if moneyUnit[v] != 0 { unit = moneyUnit[v] break } } if unit != float64(0) { //取第一个 break } } if unit == float64(0) { data[0] = fnum } else { data[0] = fnum * unit } if unit == 10000 { return data, false } else { return data, true } } //大写数子金额转换 func capitalMoney(data []interface{}) []interface{} { nodes := []float64{} node := float64(0) tmp := float64(0) decimals := 0.0 ishaspoint := false //是否含小数点 fnum := float64(0) moneyRegChar.ReplaceAllStringFunc(fmt.Sprint(data[0]), func(key string) string { if key == "元" || key == "圆" || key == "点" { ishaspoint = true } if v, ok := moneyChar[key].(float64); ok { if (ishaspoint && v > 10) || key == "整" || key == "正" { //排除后面有其他的单位 return "" } //log.Println(key, v, fnum) if v < 10 && v >= 0 { if ishaspoint { //小数部分 if v >= 1 { fnum = v } else if v < 1 && v > 0 { decimals += fnum * v } } else { if tmp != float64(0) { node += tmp } tmp = float64(v) } } else if v == 10000 || v == 100000000 { //单位万、亿 if tmp != float64(0) { node += tmp tmp = float64(0) } nodes = append(nodes, node*float64(v)) node = float64(0) } else { if v == 10 && tmp == 0 { tmp = 1 } tmp = tmp * float64(v) node += tmp tmp = float64(0) } } return "" }) nodes = append(nodes, node, tmp) ret := float64(0) for _, v := range nodes { ret = ret + v } return []interface{}{ret + decimals, data[1]} } //过滤符号 func replaceSymbol(con string, rep []string) string { for _, v := range rep { con = strings.Replace(con, v, "", -1) } return con } //符号替换 func replaceString(con string, ret, rep []string) string { for k, v := range ret { if len(rep) > k { con = strings.Replace(con, v, rep[k], -1) } } return con } //费率转小数 func RateToFloat(con []interface{}) []interface{} { tmp := fmt.Sprint(CutAllSpace(con)[0]) if strings.Contains(tmp, "%") || strings.Contains(tmp, "%") { tmp = strings.Replace(tmp, "%", "", -1) tmp = strings.Replace(tmp, "%", "", -1) rep := ObjToFloat([]interface{}{tmp, con[1]})[0] con[0] = rep.(float64) / 100 return con } else { return ObjToFloat([]interface{}{tmp, con[1]}) } } //大于一万亿的过滤掉 func ClearMaxAmount(data []interface{}) []interface{} { value, _ := data[0].(float64) if value >= 1000000000000 { data[0] = float64(0) } return data }