dongzanxun2790 2017-07-13 11:18
浏览 76
已采纳

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

I am puzzled how to parse a "float-string" to a float, based on knowing the i18n-locale but not making presumptions about the string.

Example: Germans, like me, write "1.234,87" when Americans write "1,234.87". In my project I do know what locale I do expect, but I do not want to "hard code" what presumptions I have about how that local writes that stuff.

I would hate to do regexp/stringreplacements.

Is there a generic way to say something like

myFloat := ParseFloatByLocale("1.234,76", "DE-DE")
// myFloat => 1234.76

strconvdoesn't seem to have this functionality, neither does x/text/language

Grateful for any hints!

  • 写回答

1条回答 默认 最新

  • duanqin4238 2017-07-13 21:33
    关注

    Your best bet is the use the standard library's strconv. You can make your own wrappers and locale stuff. Eventually I'd add more error checking and turn this into it's own package, but here is an idea. If you haven't found a package yet there is a good chance you will have to write your own. For a more general solution, you'd have to think about every possible input.. normalize that per locale and enforce those rules when others are using your tools... That would be a more complex solution given the number of if statements and pieces of logic.. The good part is that you know the type of input strconv.ParseFloat expects.. So all you really have to do is take the user input and transform it to the programmatic standard http://floating-point-gui.de/formats/fp/. Given numbers are mostly universal, with the exception of commas and decimal points, there shouldn't be many use cases. You might even be able to generalize further and say there are two main formats.. https://www.quora.com/Why-do-some-countries-use-a-period-and-others-use-a-comma-to-separate-large-numbers, which is largely broken down to Europe et al and British/American, where German uses the standard almost all of Europe does. Under that assumption there isn't really much to do as the use cases comes down to 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)
    
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 乌班图ip地址配置及远程SSH
  • ¥15 怎么让点阵屏显示静态爱心,用keiluVision5写出让点阵屏显示静态爱心的代码,越快越好
  • ¥15 PSPICE制作一个加法器
  • ¥15 javaweb项目无法正常跳转
  • ¥15 VMBox虚拟机无法访问
  • ¥15 skd显示找不到头文件
  • ¥15 机器视觉中图片中长度与真实长度的关系
  • ¥15 fastreport table 怎么只让每页的最下面和最顶部有横线
  • ¥15 java 的protected权限 ,问题在注释里
  • ¥15 这个是哪里有问题啊?