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
函数。