根据go中的语言环境将货币/浮点字符串解析为浮点类型

时间:2017-07-13 11:18:08

标签: string parsing go type-conversion

我很困惑如何解析" float-string"基于知道i18n-locale而不是对字符串做出推定的浮点数。

示例:德国人和我一样,写着" 1.234,87"当美国人写作#1,2; 1,234.87"。在我的项目中,我确实知道我期望的语言环境,但我不想"硬代码"关于当地人如何写这些东西,我有什么假设。

我不想做regexp / stringreplacements。

是否有通用的方式来说出像

这样的内容
myFloat := ParseFloatByLocale("1.234,76", "DE-DE")
// myFloat => 1234.76

strconv似乎没有此功能,x/text/language

也没有

感谢任何提示!

2 个答案:

答案 0 :(得分:3)

您最好的选择是使用标准库strconv。你可以制作自己的包装和区域设置。最后,我添加了更多错误检查并将其转换为自己的包,但这是一个想法。如果您还没找到包裹,那么很有可能您必须自己编写。对于更通用的解决方案,您必须考虑每个可能的输入..规范化每个语言环境并在其他人使用您的工具时强制执行这些规则......考虑到if语句的数量,这将是一个更复杂的解决方案逻辑部分..好的部分是你知道输入strconv.ParseFloat所期望的类型。所以你真正需要做的就是接受用户输入并将其转换为程序标准http://floating-point-gui.de/formats/fp/。鉴于数字通常是通用的,除了逗号和小数点之外,不应该有很多用例。你甚至可以进一步概括,并说有两种主要格式...... https://www.quora.com/Why-do-some-countries-use-a-period-and-others-use-a-comma-to-separate-large-numbers,主要分为欧洲等人和英国/美国人,德国人几乎都使用欧洲的标准。在这个假设下,由于用例降至2,所以没有什么可做的。

package main

import (
    "fmt"
    "log"
    "strconv"
    "strings"
)

func normalizeGerman(old string) string {
    s := strings.Replace(old, ",", ".", -1)
    return strings.Replace(s, ".", "", 1)
}
func normalizeAmerican(old string) string {
    return strings.Replace(old, ",", "", -1)
}

var locale map[string]func(string) string

func init() {
    locale = make(map[string]func(string) string)
    locale["DE-DE"] = normalizeGerman
    locale["US"] = normalizeAmerican
}

func main() {
    var f, f2 float64
    var err error
    // german
    if val, ok := locale["DE-DE"]; ok {
        f, err = strconv.ParseFloat(val("1.234,87"), 64)
        if err != nil {
            log.Fatal("german fail", err)
        }
    }
    //american
    if val, ok := locale["US"]; ok {
        f2, err = strconv.ParseFloat(val("1,234.87"), 64)
        if err != nil {
            log.Fatal("american fail", err)
        }
    }

    fmt.Println(f, f2)

}

答案 1 :(得分:0)

/x/text不幸的是(没有公开)您需要的所有内容,但是我能够利用它来构建运行良好的东西,并与/ x / text集成以选择区域设置

// Locale-aware number parsing with lxstrconv
//
// Docs: https://godoc.org/tawesoft.co.uk/go/lxstrconv

package main

import (
    "fmt"
    "golang.org/x/text/language"
    "tawesoft.co.uk/go/lxstrconv"
)

func checked(f float64, e error) float64 {
    if e != nil {
        panic(e)
    }
    return f
}

func main() {
    dutch   := lxstrconv.NewDecimalFormat(language.Dutch)
    british := lxstrconv.NewDecimalFormat(language.BritishEnglish)
    arabic  := lxstrconv.NewDecimalFormat(language.Arabic)

    fmt.Printf("%f\n", checked(british.ParseFloat("1,234.56")))
    fmt.Printf("%f\n", checked(dutch.ParseFloat("1.234,56")))
    fmt.Printf("%f\n", checked(arabic.ParseFloat("١٬٢٣٤٫٥٦")))
}