ZetCode

Golang strconv.IsPrint

最后修改于 2025 年 4 月 20 日

本教程将介绍如何在 Go 中使用 strconv.IsPrint 函数。我们将通过实际示例讲解可打印字符的检查。

strconv.IsPrint 函数用于检查一个 rune 是否是可打印的。当一个 rune 在 Go 的 Unicode 表中被定义为可打印时,它就被认为是可打印的。

可打印字符包括字母、数字、标点符号、符号以及 ASCII 空格字符。控制字符和其他不可见 rune 不被认为是可打印的。

基本的 strconv.IsPrint 示例

strconv.IsPrint 最简单的用法是检查一个 rune 是否是可打印的。这里我们演示了检查各种 rune。

basic_isprint.go
package main

import (
    "fmt"
    "strconv"
)

func main() {
    runes := []rune{'A', ' ', '\n', '€', '\t'}
    
    for _, r := range runes {
        if strconv.IsPrint(r) {
            fmt.Printf("%U '%c' is printable\n", r, r)
        } else {
            fmt.Printf("%U is not printable\n", r)
        }
    }
}

我们测试了几个 rune,包括字母、空格、换行符、欧元符号和制表符。该函数根据 Go 的 Unicode 表正确地识别了哪些 rune 是可打印的。

检查字符串字符

strconv.IsPrint 可以检查字符串中的每个字符。此示例演示了如何验证整个字符串的可打印性。

string_check.go
package main

import (
    "fmt"
    "strconv"
)

func main() {
    str := "Hello\tWorld\n"
    
    for i, r := range str {
        if strconv.IsPrint(r) {
            fmt.Printf("Character %d: '%c' is printable\n", i, r)
        } else {
            fmt.Printf("Character %d: %U is not printable\n", i, r)
        }
    }
}

我们遍历字符串中的每个 rune 并检查其可打印性。制表符和换行符被正确识别为不可打印字符。

过滤不可打印字符

此示例演示了如何使用 strconv.IsPrint 从字符串中过滤掉不可打印字符。

filter_chars.go
package main

import (
    "fmt"
    "strconv"
)

func main() {
    input := "Hello\x07World\x1B[31m"
    var output []rune
    
    for _, r := range input {
        if strconv.IsPrint(r) {
            output = append(output, r)
        }
    }
    
    fmt.Println("Original:", input)
    fmt.Println("Filtered:", string(output))
}

我们从字符串中移除了不可打印字符(响铃符和 ANSI 转义序列)。过滤后的结果仅包含可打印字符。

与 unicode.IsPrint 比较

Go 的 unicode 包中有一个类似的函数。此示例将 strconv.IsPrintunicode.IsPrint 进行比较。

compare_unicode.go
package main

import (
    "fmt"
    "strconv"
    "unicode"
)

func main() {
    runes := []rune{'A', '\n', ' ', '€', '\x7f'}
    
    for _, r := range runes {
        sp := strconv.IsPrint(r)
        up := unicode.IsPrint(r)
        fmt.Printf("%U: strconv.IsPrint=%t, unicode.IsPrint=%t\n", 
            r, sp, up)
    }
}

这两个函数在大多数情况下是等效的,但在某些边缘情况下可能有所不同。两者都认为空格是可打印的,而控制字符是不可打印的。

验证用户输入

此示例展示了如何使用 strconv.IsPrint 来验证用户输入是否仅包含可打印字符。

validate_input.go
package main

import (
    "bufio"
    "fmt"
    "os"
    "strconv"
    "strings"
)

func main() {
    reader := bufio.NewReader(os.Stdin)
    fmt.Print("Enter text: ")
    input, _ := reader.ReadString('\n')
    input = strings.TrimSpace(input)
    
    for i, r := range input {
        if !strconv.IsPrint(r) {
            fmt.Printf("Invalid character at position %d: %U\n", i, r)
            return
        }
    }
    
    fmt.Println("Input is valid:", input)
}

我们读取用户输入并检查每个字符的可打印性。程序会拒绝包含任何不可打印字符的输入。

处理多字节字符

strconv.IsPrint 可以正确处理多字节 Unicode 字符。此示例演示了如何检查各种 Unicode 字符。

unicode_chars.go
package main

import (
    "fmt"
    "strconv"
)

func main() {
    chars := []rune{
        'A',         // ASCII
        'é',         // Latin-1 Supplement
        '你',        // CJK Unified Ideographs
        '\u2028',    // Line Separator
        '\U0001F600', // Emoji
    }
    
    for _, r := range chars {
        fmt.Printf("%U '%c': %t\n", r, r, strconv.IsPrint(r))
    }
}

该函数能够正确识别 ASCII、带重音字符、CJK 汉字和表情符号的可打印性。行分隔符被正确标记为不可打印。

实际示例:日志清理

这个实际示例演示了如何使用 strconv.IsPrint 通过替换不可打印字符来清理日志消息。

log_sanitize.go
package main

import (
    "fmt"
    "strconv"
    "strings"
)

func sanitizeLog(msg string) string {
    var b strings.Builder
    
    for _, r := range msg {
        if strconv.IsPrint(r) {
            b.WriteRune(r)
        } else {
            b.WriteString(fmt.Sprintf("\\x%02x", r))
        }
    }
    
    return b.String()
}

func main() {
    logMsg := "User\x07 tried to access \x1B[31mrestricted\x1B[0m area"
    fmt.Println("Original log:", logMsg)
    fmt.Println("Sanitized log:", sanitizeLog(logMsg))
}

我们将不可打印字符替换为它们的十六进制转义序列。这使得日志更安全、更易读,同时保留了原始信息。

来源

Go strconv 包文档

本教程通过各种场景下的可打印字符检查的实际示例,涵盖了 Go 中的 strconv.IsPrint 函数。

作者

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

列出所有 Go 教程