Golang fmt.Sscanf 函数
最后修改时间 2025 年 5 月 8 日
本教程解释了如何在 Go 中使用 fmt.Sscanf 函数。我们将通过格式化输入的实际示例来涵盖字符串解析基础知识。
fmt.Sscanf 函数根据格式说明符扫描字符串。它将连续的、由空格分隔的值存储到参数中。这对于将结构化文本数据解析到变量中非常有用。
在 Go 中,fmt.Sscanf 提供了与 C 的 sscanf 类似的从字符串进行格式化扫描的功能。它返回成功解析的项的数量。该函数是 Go 的 fmt 包的一部分。
基本的 Sscanf 用法
fmt.Sscanf 最简单的用法是从字符串中解析基本值。此示例演示了解析整数和字符串。
注意: 格式字符串必须与输入字符串结构匹配。
package main
import (
"fmt"
)
func main() {
input := "John 25 5.9"
var name string
var age int
var height float64
n, err := fmt.Sscanf(input, "%s %d %f", &name, &age, &height)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Printf("Parsed %d values: %s is %d years old and %.1f feet tall\n",
n, name, age, height)
}
该函数将输入字符串扫描到三个变量中。返回值显示了成功解析了多少项。错误处理很重要。
解析日期组件
fmt.Sscanf 可以提取结构化数据,如日期组件。此示例展示了如何将日期字符串解析为其组成部分。
package main
import (
"fmt"
)
func main() {
dateStr := "2025-05-15"
var year, month, day int
n, err := fmt.Sscanf(dateStr, "%d-%d-%d", &year, &month, &day)
if err != nil || n != 3 {
fmt.Println("Failed to parse date")
return
}
fmt.Printf("Parsed date: Year=%d, Month=%d, Day=%d\n",
year, month, day)
}
格式字符串精确匹配日期结构。我们同时检查错误和解析项的数量以进行完整验证。
处理不同的输入格式
fmt.Sscanf 可以灵活地处理各种输入格式。此示例演示了以不同格式解析相同的数据。
package main
import (
"fmt"
)
func main() {
inputs := []string{
"Temperature: 25.5C",
"Humidity: 60%",
"Pressure: 1013hPa",
}
for _, input := range inputs {
var value float64
var unit string
_, err := fmt.Sscanf(input, "%f%s", &value, &unit)
if err != nil {
fmt.Printf("Failed to parse '%s'\n", input)
continue
}
fmt.Printf("Value: %.1f, Unit: %s\n", value, unit)
}
}
该函数会自动跳过非数字前缀。这使其可用于解析具有不同格式的半结构化数据。
使用动词修饰符进行解析
格式动词可以包含宽度说明符和其他修饰符。此示例展示了使用动词修饰符的高级解析。
package main
import (
"fmt"
)
func main() {
logEntry := "[ERROR] 2025/05/15 14:30:22 Connection timeout"
var level, date, time, message string
n, err := fmt.Sscanf(logEntry, "[%7s] %10s %8s %[^\n]",
&level, &date, &time, &message)
if err != nil || n != 4 {
fmt.Println("Failed to parse log entry")
return
}
fmt.Printf("Level: %s\nDate: %s\nTime: %s\nMessage: %s\n",
level, date, time, message)
}
宽度说明符 (%7s) 和扫描集 (%[^\n]) 提供了对解析的精确控制。这对于结构化日志非常有用。
解析十六进制和二进制值
fmt.Sscanf 支持以不同基数解析数字。此示例演示了十六进制和二进制数解析。
package main
import (
"fmt"
)
func main() {
colorStr := "Hex: #FF00FF, Binary: 101010"
var r, g, b int
var binary int
n, err := fmt.Sscanf(colorStr, "Hex: #%2x%2x%2x, Binary: %b",
&r, &g, &b, &binary)
if err != nil || n != 4 {
fmt.Println("Failed to parse values")
return
}
fmt.Printf("Color: R=%d, G=%d, B=%d\nBinary: %d\n",
r, g, b, binary)
}
%x 动词解析十六进制值,而 %b 解析二进制值。格式动词匹配 fmt.Printf 中使用的动词。
忽略输入部分
您可以使用 * 修饰符跳过输入的部分。此示例显示了如何忽略不需要的文本部分。
package main
import (
"fmt"
)
func main() {
data := "Name: John, Age: 25, City: New York"
var name string
var age int
n, err := fmt.Sscanf(data, "Name: %s, Age: %d, City: %*s",
&name, &age)
if err != nil || n != 2 {
fmt.Println("Failed to parse data")
return
}
fmt.Printf("Name: %s, Age: %d\n", name, age)
}
%*s 动词会扫描但不存储城市值。当您需要跳过不相关的数据时,此技术非常有用。
解析复杂结构
fmt.Sscanf 可以通过仔细的格式化来解析嵌套结构。此示例演示了如何解析复杂的配置文件字符串。
package main
import (
"fmt"
)
func main() {
config := "Server{IP:192.168.1.1, Port:8080, Active:true}"
var ip1, ip2, ip3, ip4 int
var port int
var active bool
n, err := fmt.Sscanf(config,
"Server{IP:%d.%d.%d.%d, Port:%d, Active:%t}",
&ip1, &ip2, &ip3, &ip4, &port, &active)
if err != nil || n != 6 {
fmt.Println("Failed to parse config")
return
}
fmt.Printf("Server: %d.%d.%d.%d:%d, Active: %t\n",
ip1, ip2, ip3, ip4, port, active)
}
格式字符串精确匹配结构。每个组件都被解析到单独的变量中。这种方法适用于许多文本格式。
来源
本教程通过字符串解析和格式化输入扫描的实际示例,涵盖了 Go 中的 fmt.Sscanf 函数。