ZetCode

Golang fmt.Sscanf 函数

最后修改时间 2025 年 5 月 8 日

本教程解释了如何在 Go 中使用 fmt.Sscanf 函数。我们将通过格式化输入的实际示例来涵盖字符串解析基础知识。

fmt.Sscanf 函数根据格式说明符扫描字符串。它将连续的、由空格分隔的值存储到参数中。这对于将结构化文本数据解析到变量中非常有用。

在 Go 中,fmt.Sscanf 提供了与 C 的 sscanf 类似的从字符串进行格式化扫描的功能。它返回成功解析的项的数量。该函数是 Go 的 fmt 包的一部分。

基本的 Sscanf 用法

fmt.Sscanf 最简单的用法是从字符串中解析基本值。此示例演示了解析整数和字符串。
注意: 格式字符串必须与输入字符串结构匹配。

basic_sscanf.go
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 可以提取结构化数据,如日期组件。此示例展示了如何将日期字符串解析为其组成部分。

date_parsing.go
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 可以灵活地处理各种输入格式。此示例演示了以不同格式解析相同的数据。

multiple_formats.go
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)
    }
}

该函数会自动跳过非数字前缀。这使其可用于解析具有不同格式的半结构化数据。

使用动词修饰符进行解析

格式动词可以包含宽度说明符和其他修饰符。此示例展示了使用动词修饰符的高级解析。

verb_modifiers.go
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 支持以不同基数解析数字。此示例演示了十六进制和二进制数解析。

number_bases.go
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 中使用的动词。

忽略输入部分

您可以使用 * 修饰符跳过输入的部分。此示例显示了如何忽略不需要的文本部分。

ignoring_parts.go
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 可以通过仔细的格式化来解析嵌套结构。此示例演示了如何解析复杂的配置文件字符串。

complex_parsing.go
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 包文档

本教程通过字符串解析和格式化输入扫描的实际示例,涵盖了 Go 中的 fmt.Sscanf 函数。

作者

我叫 Jan Bodnar,是一位热情的程序员,拥有丰富的编程经验。我自 2007 年以来一直在撰写编程文章。迄今为止,我已撰写了 1,400 多篇文章和 8 本电子书。我在教授编程方面拥有十多年的经验。

列出所有 Golang 教程