package main import ( "fmt" "regexp" "strconv" "strings" ) var ( regOperator, _ = regexp.Compile(`[*|+|)*)]`) regNumFloat, _ = regexp.Compile(`([1-9]\d*|0)(\.\d+)?`) regStrUnit, _ = regexp.Compile(`[元|万|亿]`) regStrChar = `[〇|零|点|壹|贰|叁|肆|伍|陆|柒|捌|玖|拾|百|佰|千|仟|万|亿|億|元|圆|角|分|整|正]` moneyRegChar, _ = regexp.Compile(regStrChar) contentUnit, _ = regexp.Compile(`(万元|单位/万)`) numCapitals, _ = regexp.Compile(`([〇|零|点|壹|贰|叁|肆|伍|陆|柒|捌|玖|拾|百|佰|千|仟|万|亿|億|元|圆|角|分|整|正]{4,40})`) regQianw, _ = regexp.Compile(`\d{1,2}千万`) 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), } moneyUnit = map[string]float64{ "元": float64(1), "万": float64(10000), "亿": float64(100000000), "億": float64(100000000), //单位 } cutAllSpace, _ = regexp.Compile(`\s*`) spaces = []string{"\u3000", "\u2003", "\u00a0", "\t", "\r", "\n"} ) //大写数子金额转换 func capitalMoney(data []interface{}) []interface{} { nodes := []float64{} node := float64(0) tmp := float64(0) decimals := 0.0 ishaspoint := false //是否含小数点 fnum := float64(0) end := false str := fmt.Sprint(data[0]) //提取第一个大写信息 strmatch := numCapitals.FindAllStringSubmatch(str, -1) if len(strmatch) > 0 { str = strmatch[0][0] } suffixUnit := float64(1) if strings.HasSuffix(str, "万") || strings.HasSuffix(str, "万元") || strings.HasSuffix(str, "万元整") { index := strings.LastIndex(str, "万") str = str[0:index] suffixUnit = float64(10000) } moneyRegChar.ReplaceAllStringFunc(str, func(key string) string { if key == "元" || key == "圆" || key == "点" { ishaspoint = true } if v, ok := moneyChar[key].(float64); ok && !end { if ishaspoint && v > 10 { //排除后面有其他的单位 return "" } //fmt.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) } } if key == "整" || key == "正" || key == "分" { end = true } return "" }) nodes = append(nodes, node, tmp) ret := float64(0) for _, v := range nodes { ret += v } return []interface{}{(ret + decimals) * suffixUnit, 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 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 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.Sprintf("%f", data[0]) repUnit := float64(1) if regQianw.MatchString(tmp) { tmp = strings.Replace(tmp, "千万", "万", -1) repUnit = float64(1000) } 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 } } fnum = fnum * repUnit if unit == float64(0) { data[0] = fnum } else { data[0] = fnum * unit } if unit == 10000 { return data, false } else { return data, true } } //过滤符号 func replaceSymbol(con string, rep []string) string { for _, v := range rep { con = strings.Replace(con, v, "", -1) } return con }