如何从不寻常的格式(例如2.93B,201k)将字符串转换为浮点数?使用正常方法不起作用,即:
i, err := strconv.ParseFloat("2.93B", 64) // Returns an 'invalid syntax' error
答案 0 :(得分:3)
例如,
package main
import (
"fmt"
"strconv"
"unicode/utf8"
)
var siFactors = map[string]float64{
"": 1e0,
"k": 1e3,
"M": 1e6, // Sometimes, M (Roman numeral) for thousands and MM for millions
"G": 1e9,
"T": 1e12,
"P": 1e15,
"E": 1e18,
"Z": 1e21,
"Y": 1e24,
"K": 1e3, // colloquial synonym for "k"
"B": 1e9, // colloquial synonym for "G"
}
func parseNumber(s string) (float64, error) {
f, err := strconv.ParseFloat(s, 64)
if err == nil {
return f, nil
}
r, size := utf8.DecodeLastRuneInString(s)
if r == utf8.RuneError {
return 0, err
}
symbol := s[len(s)-size : len(s)]
factor, ok := siFactors[symbol]
if !ok {
return 0, err
}
f, e := strconv.ParseFloat(s[:len(s)-len(symbol)], 64)
if e != nil {
return 0, err
}
return f * factor, nil
}
func main() {
for _, s := range []string{"2.93", "2.93k", "2.93M", "2.93G", "2.93B", "2930000000", "2.93X", "G"} {
n, err := parseNumber(s)
fmt.Printf("%q\t %g %v\n", s, n, err)
}
}
游乐场:https://play.golang.org/p/DYEe5gQ8pl
输出:
"2.93" 2.93 <nil>
"2.93k" 2930 <nil>
"2.93M" 2.93e+06 <nil>
"2.93G" 2.93e+09 <nil>
"2.93B" 2.93e+09 <nil>
"2930000000" 2.93e+09 <nil>
"2.93X" 0 strconv.ParseFloat: parsing "2.93X": invalid syntax
"B" 0 strconv.ParseFloat: parsing "B": invalid syntax