如何在golang中将字符串转换为整数

eeq64g8w  于 2023-03-10  发布在  Go
关注(0)|答案(9)|浏览(199)

我想把字符串转换成golang中的整数,但是我不知道字符串的格式。例如,"10"-〉10"65.0"-〉65"xx"-〉0,“11 xx”-〉11,“xx 11”-〉0
我做了一些搜索,找到了strconv.ParseInt()。但是它不能处理"65.0"。所以我必须检查字符串的格式。
有更好的办法吗?

5us2dqdw

5us2dqdw1#

从一个字符串的开头提取一个int型是我最常做的事情之一,在C语言中你可以使用atoi()或者strtol(),但是Go语言却没有一个std库函数来做这件事,这是很可笑的,不管怎样,这里有一个我刚刚总结出来的函数:

// strToInt gets the integer from the start of the string.
// It returns the value and the offset of the first non-digit.
func StrToInt(s string) (v int, offset int) {
    offset = strings.IndexFunc(s, func(r rune) bool { return r < '0' || r > '9' })
    if offset == -1 { offset = len(s) }
    if offset == 0 { return }   // Avoid Atoi on empty string
    v, _ = strconv.Atoi(s[:offset])
    return
}

如果你想处理-ve整数,你需要稍微修改一下。

nc1teljy

nc1teljy2#

我目前的解决方案是:

// Convert string to integer in best effort.                                                                                
 // TODO: handle overflow and add unittest                                                                                   
func StrToInt(str string) (int64, error) {                                                                                  
    if len(str) == 0 {                                                                                                      
        return 0, nil                                                                                                       
     }                                                                                                                       
     negative := false                                                                                                       
     i := 0                                                                                                                  
     if str[i] == '-' {                                                                                                      
         negative = true                                                                                                     
         i++                                                                                                                 
     } else if str[i] == '+' {                                                                                               
         i++                                                                                                                 
     }                                                                                                                       
     r := int64(0)                                                                                                           
     for ; i < len(str); i++ {                                                                                             
         if unicode.IsDigit(rune(str[i])) {                                                                                  
             r = r*10 + int64(str[i]-'0')                                                                                    
         } else {
             break
          }                                                                                                                   
     }                                                                                                                       
     if negative {                                                                                                           
         r = -r                                                                                                              
     }                                                                                                                       
     // TODO: if i < len(str), we should return error                                                                        
     return r, nil                                                                                                           
 }
pxq42qpu

pxq42qpu3#

import (
  "strconv"
  "strings"
)

func StrToInt(str string) int {
  // Delete any non-numeric character from the string
  str = strings.TrimFunc(str, func(r rune) bool {
      return r < '0' || r > '9'
  })

  // Convert the cleaned-up string to an integer
  n, _ := strconv.Atoi(str)
  return n
}
5hcedyr0

5hcedyr04#

我相信你要找的功能是

strconv.ParseFloat()

参见示例here
但该函数的返回类型为float64。
如果你不需要以字符串形式传递的数字的小数部分,下面的函数可以完成这项工作:

func StrToInt(str string) (int, error) {
    nonFractionalPart := strings.Split(str, ".")
    return strconv.Atoi(nonFractionalPart[0])
}
dly7yett

dly7yett5#

可以使用这三个函数将字符串值转换为整数或浮点型。
注意:要执行这些功能,必须导入strconv内置包。

  1. func Atoi(s string) (int, error)
  2. func ParseInt(s string, base int, bitSize int) (i int64, err error)
  3. func ParseFloat(s string, bitSize int) (float64, error)
package main

import (
    "fmt"
    "strconv"
)

func main() {
    i, _ := strconv.Atoi("-42")
    fmt.Println(i)

    j,_ := strconv.ParseInt("-42", 10, 8)
    fmt.Println(j)

    k,_ := strconv.ParseFloat("-42.8", 8)
    fmt.Println(k)
}
cgfeq70w

cgfeq70w6#

package main

import "strconv"
import "fmt"

// The built-in package "strconv" provides the number parsing.

// For `ParseInt`, the `0` means infer the base from
// the string. `64` requires that the result fit in 64
// bits.

value, err := strconv.ParseInt("123", 0, 64)
if err != nil {
    panic(err)
}
fmt.Println(value)

For reference, Click Here
如果总是需要相同的值,也可以传递非零基数(如10)。

30byixjq

30byixjq7#

我想在golang中将字符串转换为整数。
正如您已经提到的,有一个strconv.ParseInt函数可以完成这个任务!
但是我不知道字符串的格式。
这听起来很可怕(也很有挑战性),但看过你的例子后,我可以很容易地得出结论,你知道格式,问题可以这样陈述:

  • 如何将字符串的初始部分解析为整数?*

因为strconv.ParseInt在语法错误时返回0,所以这不是一个很好的匹配;嗯,至少不是一个很好的直接匹配。但是如果你 * 提取 * 它,它 * 可以 * 解析你的初始部分。我相信你已经找到了,但是这确实是最干净的解决方案:从字符串中提取内容,解析它
您可以通过几种方式提取前导整数,其中之一是使用regexp

package main

import (
    "fmt"
    "regexp"
    "strconv"
)

// Extract what you need
var leadingInt = regexp.MustCompile(`^[-+]?\d+`)

func ParseLeadingInt(s string) (int64, error) {
    s = leadingInt.FindString(s)
    if s == "" { // add this if you don't want error on "xx" etc
        return 0, nil
    }
    return strconv.ParseInt(s, 10, 64)
}

func main() {
    for _, s := range []string{"10", "65.0", "xx", "11xx", "xx11"} {
        i, err := ParseLeadingInt(s)
        fmt.Printf("%s\t%d\t%v\n", s, i, err)
    }
}

http://play.golang.org/p/d7sS5_WpLj
我相信这段代码简单明了,你也使用了标准的ParseInt,它可以工作,并提供了你需要的所有错误检查。
如果出于任何原因,你无法提取前导整数(你需要它以极快的速度解析TB级的数据,而你的老板却在对你大喊大叫,他们现在就需要它,昨天更好,所以弯曲时间,交付它:hiss:),那么我建议你深入研究源代码,修改标准解析器,使其不报告语法错误,而是返回字符串的解析部分。

6vl6ewon

6vl6ewon8#

为了补充@MayankPatel和@DeepakG给出的完美答案,可以将字符串设置为各种数值类型。可以将各种数值类型设置为字符串。同样,可以将“true”设置为bool,将true设置为字符串。

package main

import (
    "fmt"
    "strconv"
)

func main() {
    //convert a string to another type
    f, _ := strconv.ParseFloat("70.99", 64)
    i, _ := strconv.Atoi(fmt.Sprintf("%.f", f))
    t, _ := strconv.ParseBool("true")
    c := []interface{}{[]byte("70.99"), f, i, rune(i), t}
    checkType(c) //[]uint8 [55 48 46 57 57], float64 70.99, int 71, int32 71, bool true

    //convert another type to a string
    c = []interface{}{fmt.Sprintf("%s", []byte("70.99")), fmt.Sprintf("%.f", f), strconv.Itoa(i), string(rune(i)), strconv.FormatBool(t)}
    checkType(c) //string 70.99, string 71, string 71, string G, string true
}

func checkType(s []interface{}) {
    for k, _ := range s {
        fmt.Printf("%T %v\n", s[k], s[k])
    }
}

字符串类型表示字符串值的集合。字符串值是一个字节序列(可能为空)。字节数称为字符串的长度,并且决不能为负数。字符串是不可变的。请参阅https://Golang.org/ref/spec#String_types。
下面是将字符串解析为整数的三种方法,从运行时最快到最慢:1. strconv.ParseInt(...)最快2. strconv.Atoi(...)仍然非常快3. fmt.Sscanf(...)不是特别快,但是最灵活。参见https://stackoverflow.com/a/47317150/12817546
避免将字符串转换为[]byte:B:= []byte(s).它分配一个新的内存空间,并将全部内容复制到其中.参见https://stackoverflow.com/a/52943136/12817546.参见https://stackoverflow.com/a/41460993/12817546.引文编辑

sczxawaw

sczxawaw9#

您可以编写一个FieldsFunc来单独解析和获取数字值。
Play it here

package main

import (
    "fmt"
    "strconv"
    "strings"
    "unicode"
)

func stripNonIntFloat(s string) string {
    f := func(c rune) bool {
        return !unicode.IsNumber(c) && (c != 46)
    }
    output := strings.FieldsFunc(s, f)
    if len(output) > 0 {
        return output[0]
    } else {
        return ""
    }
}

func main() {
    strList := []string{"10", "65.0", "xx", "11xx", "xx11"}
    for i := 0; i < len(strList); i++ {
        s := stripNonIntFloat(strList[i])
        v, err := strconv.ParseFloat(s, 10)
        if err != nil {
            fmt.Println(strList[i], 0)
        } else {
            fmt.Println(strList[i], v)
        }
    }
}

此处的输出为

10 10
65.0 65
xx 0
11xx 11
xx11 11

请注意,xx11的最后一个条件将其作为11处理。

相关问题