我想检查字符串是否为数字。
例如:
for row in data:
Year,busnum,busname,scaled_power,tla,Location,Yearlink,From,To,Max,Min = row[0:11]
if Yearlink==year and Location==location:
for From,To,Max,Min in data:
From=int(From)
To=int(To)
Max=float(Max)
Min=float(Min)
print('From Bus #: %d\t' % From ,'To Bus #: %d\t'% To,'VMAX: %d pu\t' % Max, 'VMIN: %d pu\t' % Min)
else:
exit
应该返回"abcd123"
。 false
或"1.4"
应返回"240"
。 我考虑过使用true
和ParseInt
(来自ParseFloat
包),但我不确定这是否正确。
答案 0 :(得分:6)
我在考虑使用strconv ParseInt和ParseFloat但不确定 如果这是正确的方式。
嗯,这肯定是 正确的方式。
但是,您不需要使用ParseInt。 ParseFloat将完成这项工作。
func isNumeric(s string) bool {
_, err := strconv.ParseFloat(s, 64)
return err == nil
}
请在此处查看示例:https://play.golang.org/p/D53HRS-KIL
答案 1 :(得分:2)
如果您需要将字符串转换为浮点数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
}
这个(21.7秒 - 做更多的额外工作“将字符串转换为浮点数”):
func isNumeric(s string) bool {
_, err := strconv.ParseFloat(s, 64)
return err == nil
}
试一试:
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)
}
输出:
true
false
false
false
1.7822s
false
21.723s
false
答案 2 :(得分:1)
您可以使用strconv.Atoi
函数检查整数值,使用strconv.ParseFloat
表示浮点值。以下是一个例子:
package main
import (
"fmt"
"strconv"
)
func main() {
v1 := "14"
if _, err := strconv.Atoi(v1); err == nil {
fmt.Printf("%q looks like a number.\n", v1)
} else {
fmt.Printf("%q is not a number.\n", v1)
}
v2 := "1.4"
if _, err := strconv.ParseFloat(v2, 64); err == nil {
fmt.Printf("%q looks like a float.\n", v2)
} else {
fmt.Printf("%q is not a float.\n", v2)
}
}
/* Output:
"14" looks like a number.
"1.4" looks like a float.
*/
您可以在Go Playground上查看。
答案 3 :(得分:1)
所有答案都有效,但尚未提出另一个选项:
re := regexp.MustCompile(`^[0-9]+(\.[0-9]+)?$`)
isNum := re.Match([]byte("ab123"))
答案 4 :(得分:0)
我试图评论Adrian的答案,但我想我的声誉得分不足。基于他出色的反应,这是使用PCRE的一种变体。如果您不熟悉正则表达式,请对符号进行一些简要说明:
“ ^”匹配输入的开头(即字符串的开头)
“ $”匹配输入的结尾(即字符串的结尾)
“()”是分组运算符
“ *”匹配0或更多
“ +”匹配1个或更多
”?完全匹配0或1
“ \ d”是一个字符类,代表字符值0到9
因此,以下内容至少需要前导0,允许为“ 0.”,以及通常标识为浮点值的所有其他内容。您可以尝试一下。
func isFloat(s string) bool {
return regexp.MatchString(`^\d+(\.\d*)?$`, s)
}
自然,如果您要调用此函数来验证数据,则应将其清除:
str := strings.TrimSpace(someString)
if isFloat(str) {
...
}
仅适用于ASCII字符。如果您要处理UTF8或其他多字节字符集(MBCS),则可以使用regexp来完成,但是还需要做更多的工作,也许还需要另一种方法。
答案 5 :(得分:0)
我今天在一个高吞吐量系统中遇到了这个问题,并对三个建议进行了基准测试。结果:
BenchmarkNumDot-4:657966132:18.2 ns/op
BenchmarkNumeric-4:49575919:226 ns/op
基准Regexp-4:18817201:628 ns/op
代码如下,因为 Playground 不支持基准测试。
package main
import (
"regexp"
"strconv"
"testing"
)
func BenchmarkNumDot(b *testing.B) {
for i := 0; i < b.N; i++ {
isNumDot("abc")
isNumDot("123")
isNumDot("12.34")
isNumDot("1.2.3.4")
}
}
func BenchmarkNumeric(b *testing.B) {
for i := 0; i < b.N; i++ {
isNumeric("abc")
isNumeric("123")
isNumeric("12.34")
isNumeric("1.2.3.4")
}
}
func BenchmarkRegexp(b *testing.B) {
re := regexp.MustCompile(`^[0-9]+(\.[0-9]+)?$`)
for i := 0; i < b.N; i++ {
isNumReg("abc", re)
isNumReg("123", re)
isNumReg("12.34", re)
isNumReg("1.2.3.4", re)
}
}
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 isNumReg(s string, re *regexp.Regexp) bool {
return re.Match([]byte(s))
}