如何在Golang中编写isNumeric函数?

Cru*_*yro 1 go

我想检查一个字符串是否是数字.

例如:

  • "abcd123"应该回来false.
  • "1.4"或者"240"应该回来true.

我想过使用ParseIntParseFloat(从strconv包中),但我不确定这是否正确.

Wal*_*vis 8

我在考虑使用strconv ParseInt和ParseFloat,但不确定这是否正确.

嗯,这肯定正确的方式.

但是,您不需要使用ParseInt.ParseFloat将完成这项工作.

func isNumeric(s string) bool {
    _, err := strconv.ParseFloat(s, 64)
    return err == nil
}
Run Code Online (Sandbox Code Playgroud)

请参阅此处的示例:https://play.golang.org/p/D53HRS-KIL

  • 我们刚刚遇到了一个错误。如果您传递“inf”或“infinity”,它将返回错误:https://go.dev/play/p/94pIW4frlDD (2认同)

was*_*mup 6

如果需要将字符串转换为浮点数strconv.ParseFloat是首选。
在这里你只需要知道你的字符串中只有"0123456789"一个并且最大一个'.',对我isNumDot来说这里12x比 快isNumeric,请参阅:
考虑这个(1.7秒) - 针对性能进行了优化:

func isNumDot(s string) bool {
    dotFound := false
    for _, v := range s {
        if v == '.' {
            if dotFound {
                return false
            }
            dotFound = true
        } else if v < '0' || v > '9' {
            return false
        }
    }
    return true
}
Run Code Online (Sandbox Code Playgroud)

这(21.7 秒 - 做更多的额外工作“将字符串转换为浮点数”):

func isNumeric(s string) bool {
    _, err := strconv.ParseFloat(s, 64)
    return err == nil
}
Run Code Online (Sandbox Code Playgroud)

尝试一下:

package main

import (
    "fmt"
    "strconv"
    "time"
)

func isNumDot(s string) bool {
    dotFound := false
    for _, v := range s {
        if v == '.' {
            if dotFound {
                return false
            }
            dotFound = true
        } else if v < '0' || v > '9' {
            return false
        }
    }
    return true
}

func isNumeric(s string) bool {
    _, err := strconv.ParseFloat(s, 64)
    return err == nil
}

func main() {
    fmt.Println(isNumDot("240"))     //true
    fmt.Println(isNumDot("abcd123")) //false
    fmt.Println(isNumDot("0.4."))    //false
    fmt.Println(isNumDot("240 "))    //false
    benchmark(isNumDot)
    benchmark(isNumeric)
}

func benchmark(f func(string) bool) {
    var res bool
    t := time.Now()
    for i := 0; i < 100000000; i++ {
        res = f("a 240") || f("abcd123") || f("0.4.") || f("240 ")
    }
    fmt.Println(time.Since(t))
    fmt.Println(res)
}
Run Code Online (Sandbox Code Playgroud)

输出:

true
false
false
false
1.7822s
false
21.723s
false
Run Code Online (Sandbox Code Playgroud)

使用基准(isNumDot比 快isNumeric):

BenchmarkIsNumDot-8     34117197            31.2 ns/op         0 B/op          0 allocs/op
BenchmarkIsNumeric-8     1931089           630 ns/op         192 B/op          4 allocs/op

// r = isNumDot("2.22")
BenchmarkIsNumDot-8     102849996           11.4 ns/op         0 B/op          0 allocs/op
BenchmarkIsNumeric-8    21994874            48.5 ns/op         0 B/op          0 allocs/op

// r = isNumDot("a 240")
BenchmarkIsNumDot-8     256610877            4.58 ns/op        0 B/op          0 allocs/op
BenchmarkIsNumeric-8     8962381           140 ns/op          48 B/op          1 allocs/op
Run Code Online (Sandbox Code Playgroud)

基准:

package main

import (
    "testing"
)

var r bool

func BenchmarkIsNumDot(b *testing.B) {
    for i := 0; i < b.N; i++ {
        r = isNumDot("a 240") || isNumDot("abcd123") || isNumDot("0.4.") || isNumDot("240 ")
    }
}

func BenchmarkIsNumeric(b *testing.B) {
    for i := 0; i < b.N; i++ {
        r = isNumeric("a 240") || isNumeric("abcd123") || isNumeric("0.4.") || isNumeric("240 ")
    }
}
Run Code Online (Sandbox Code Playgroud)