Golang中使用ANSI转义码实现颜色和打印长度控制

Golang中使用ANSI转义码实现颜色和打印长度控制 我有一个包含 ANSI 转义码的字符串,用于以彩色打印一些内容以及一些符文。我已经知道将字符串转换为符文切片以查看有多少个码点(并给出字符串以字符为单位的打印长度),但现在我需要知道去掉转义字符后的长度,以获取真实的打印长度。

当我找到 ansi 包 - github.com/jcorbin/anansi/ansi - Go Packages 时,我以为我接近答案了,但我没有找到解决我问题的方法。

任何帮助都将不胜感激。


更多关于Golang中使用ANSI转义码实现颜色和打印长度控制的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复

如果字符串中仅包含用于选择图形渲染参数的ANSI转义序列,那么处理起来会相当简单。这类序列以“ESC[”开始,以“m”结束。

因此,下面是一种粗略计算非转义符文数量的方法。

package main

import "fmt"

func main() {
	escaped := "\x1b[1;31mred\x1b[0m\x1b[1;32mgreen\x1b[0m"

	withinEscapeSequence := false
	runeCount := 0
	for _, r := range escaped {
		if withinEscapeSequence {
			if r == 'm' {
				withinEscapeSequence = false
			}
		} else {
			if r == '\x1b' {
				withinEscapeSequence = true
			} else {
				runeCount++
			}
		}
	}

	fmt.Println(runeCount)
}

运行示例

更多关于Golang中使用ANSI转义码实现颜色和打印长度控制的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


你可以使用正则表达式来过滤ANSI转义码,然后计算纯文本的长度。以下是一个示例实现:

package main

import (
    "fmt"
    "regexp"
    "unicode/utf8"
)

var ansiEscapeRegex = regexp.MustCompile(`\x1b\[[0-9;]*[a-zA-Z]`)

func StripANSI(str string) string {
    return ansiEscapeRegex.ReplaceAllString(str, "")
}

func VisibleLength(str string) int {
    cleaned := StripANSI(str)
    return utf8.RuneCountInString(cleaned)
}

func main() {
    coloredText := "\x1b[31mHello\x1b[0m \x1b[32mWorld\x1b[0m"
    cleaned := StripANSI(coloredText)
    length := VisibleLength(coloredText)
    
    fmt.Printf("原始字符串: %q\n", coloredText)
    fmt.Printf("清理后: %q\n", cleaned)
    fmt.Printf("可见长度: %d\n", length)
    fmt.Printf("实际打印: %s\n", coloredText)
}

输出结果:

原始字符串: "\x1b[31mHello\x1b[0m \x1b[32mWorld\x1b[0m"
清理后: "Hello World"
可见长度: 11
实际打印: Hello World

这个实现会匹配所有ANSI转义序列(以\x1b[开头,包含数字和分号,以字母结尾的模式),并将其移除。然后使用utf8.RuneCountInString计算可见字符的数量。

如果你需要处理更复杂的ANSI序列,可以扩展正则表达式模式。例如,要包含更多控制字符:

var ansiEscapeRegex = regexp.MustCompile(`[\x1b\x9b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-PRZcf-nqry=><]`)

这个更全面的正则表达式能匹配更多类型的ANSI控制序列。

回到顶部