当你执行下面代码会发现,第一个a
把剩余所有字符串都获取了
package main
import (
"fmt"
"log"
)
func main() {
var (
str = "a=aaa,b=bbb,c=ccc"
format = "a=%s,b=%s,c=%s"
a string
b string
c string
)
if _, err := fmt.Sscanf(str, format, &a, &b, &c); err != nil {
log.Println(err)
}
log.Println("a:", a)
log.Println("b:", b)
log.Println("c:", c)
}
结果如下
2022/09/21 17:50:04 unexpected EOF
2022/09/21 17:50:04 a: aaa,b=bbb,c=ccc
2022/09/21 17:50:04 b:
2022/09/21 17:50:04 c:
你可以增加空格,因为scanf
默认都是已空格或者制表符之类的作为分隔,下面这种方式需要两种字符串都已空格分开
package main
import (
"fmt"
"log"
)
func main() {
var (
str = "a=aaa ,b=bbb ,c=ccc"
format = "a=%s ,b=%s ,c=%s"
a string
b string
c string
)
if _, err := fmt.Sscanf(str, format, &a, &b, &c); err != nil {
log.Println(err)
}
log.Println("a:", a)
log.Println("b:", b)
log.Println("c:", c)
}
结果如下
2022/09/21 17:54:58 a: aaa
2022/09/21 17:54:58 b: bbb
2022/09/21 17:54:58 c: ccc
下面方法我将扫描分隔符改为逗号,完全满足你的需求
package main
import (
"fmt"
"log"
)
func main() {
var (
str = "a=aaa,b=bbb,c=ccc"
format = "a=%s,b=%s,c=%s"
a, b, c string
)
if _, err := fmt.Sscanf(str, format, (*mm)(&a), (*mm)(&b), (*mm)(&c)); err != nil {
log.Println(err)
}
log.Println("a:", a)
log.Println("b:", b)
log.Println("c:", c)
}
type mm string
func (m *mm) Scan(state fmt.ScanState, verb rune) error {
tok, err := state.Token(true, func(r rune) bool {
return r != ','
})
if err != nil {
return err
}
*m = mm(tok)
return nil
}
结果如下
2022/09/21 17:55:28 a: aaa
2022/09/21 17:55:28 b: bbb
2022/09/21 17:55:28 c: ccc
我又修改了下,感觉把类型改为自定义使用起来比较麻烦。这下更完美了。
@Mericusta @yecz