scanning a string separated by ":" in golang

huangapple go评论87阅读模式
英文:

scanning a string separated by ":" in golang

问题

我已经将您提供的内容翻译成中文,如下所示:

type Origin struct {
	Lat     float64 `json:"lat" binding:"required"`
	Lng     float64 `json:"lng" binding:"required"`
	Address string  `json:"address" binding:"required"`
	Name    string  `json:"name" binding:"required"`
}

func (o *Origin) ParseString(str string) error {
	if str == "" {
		return nil
	}
	_, err := fmt.Sscanf(str, "%f:%f:%[^:]:%[^/n]", &o.Lat, &o.Lng, &o.Address, &o.Name)
	if err != nil {
		return fmt.Errorf("parsing origin: %s, input:%s", err.Error(), str)
	}
	return nil
}

func main() {
	o := &Origin{}
	o.ParseString("23.584950:58.353603:an address, str:a place, name")
	fmt.Println(o)
}

然而,结构体o打印出的结果是:&{23.58495 58.353603 }。地址和名称没有被正确地扫描。请问在Sscanf中应该使用什么正确的格式来正确解析这个字符串?

英文:

I need to string scan 23.584950:58.353603:an address, str:a place, name
into :

type Origin struct {
	Lat     float64 `json:"lat" binding:"required"`
	Lng     float64 `json:"lng" binding:"required"`
	Address string  `json:"address" binding:"required"`
	Name    string  `json:"name" binding:"required"`
}

My code:

package main

import "fmt"

type Origin struct {
	Lat     float64 `json:"lat" binding:"required"`
	Lng     float64 `json:"lng" binding:"required"`
	Address string  `json:"address" binding:"required"`
	Name    string  `json:"name" binding:"required"`
}

func (o *Origin) ParseString(str string) error {
	if str == "" {
		return nil
	}
	_, err := fmt.Sscanf(str, "%f:%f:%[^:]:%[^/n]", &o.Lat, &o.Lng, &o.Address, &o.Name)
	if err != nil {
		return fmt.Errorf("parsing origin: %s, input:%s", err.Error(), str)
	}
	return nil
}
func main() {
	o := &Origin{}
	o.ParseString("23.584950:58.353603:address, text:place, name, text")
	fmt.Println(o)
}

https://go.dev/play/p/uUTNyx2cDFB

However, struct o prints out: &{23.58495 58.353603 }. Address and name are not scanned properly. What is the correct format to be used in Sscanf to parse this string correctly?

答案1

得分: 2

你正在使用正则表达式来捕获输入,同时使用fmt.Scanfffmt.Scanff不支持正则表达式。如果你想使用正则表达式,可以使用regexp包。

或者你可以使用简单的strings.Split函数将输入解析为正确的类型:

func (o *Origin) ParseString2(str string) error {
	if str == "" {
		return nil
	}
	parts := strings.Split(str, ":")
	if len(parts) != 4 {
		return errors.New("expected format '...:...:...:...'")
	}

	f, err := strconv.ParseFloat(parts[0], 64)
	if err != nil {
		return err
	}
	o.Lat = f

	f, err = strconv.ParseFloat(parts[1], 64)
	if err != nil {
		return err
	}
	o.Lng = f
	o.Address = parts[2]
	o.Name = parts[3]

	return nil
}
英文:

You are using a regex to capture input, while using fmt.Scanff. fmt.Scanff does not support RegEx. If you want to use regex, use the regexp package.

Or you could use a simple strings.Split and parse the input to the correct type:

func (o *Origin) ParseString2(str string) error {
	if str == "" {
		return nil
	}
	parts := strings.Split(str, ":")
	if len(parts) != 4 {
		return errors.New("expected format '...:...:...:...")
	}

	f, err := strconv.ParseFloat(parts[0], 64)
	if err != nil {
		return err
	}
	o.Lat = f

	f, err = strconv.ParseFloat(parts[1], 64)
	if err != nil {
		return err
	}
	o.Lng = f
	o.Address = parts[2]
	o.Name = parts[3]

	return nil
}

huangapple
  • 本文由 发表于 2022年9月17日 19:32:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/73754483.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定