
Go 语言没有内置的字符串压缩方法,但可通过遍历 runes 并跳过连续重复字符轻松实现 Ruby 的 squeeze 行为,支持 Unicode,且需注意 UTF-8 字符边界。
go 语言没有内置的字符串压缩方法,但可通过遍历 runes 并跳过连续重复字符轻松实现 ruby 的 `squeeze` 行为,支持 unicode,且需注意 utf-8 字符边界。
在 Ruby 中,String#squeeze 是一个简洁而实用的方法:它将字符串中连续重复出现的相同字符压缩为单个字符(可全局压缩,也可限定于指定字符集)。例如 "yellow moon".squeeze 得到 "yelow mon",直观体现了“去重叠、保顺序、留一例”的语义。
Go 语言标准库未提供直接对应的函数,但实现逻辑清晰、高效且安全——关键在于:必须使用 rune 而非 byte 迭代,以正确处理 UTF-8 编码的多字节字符(如中文、emoji、带重音符号的字母等)。
以下是基础版 Squeeze 函数,实现全局压缩(即 Ruby 中无参数调用的效果):
func Squeeze(s string) string {
if len(s) == 0 {
return s
}
result := make([]rune, 0, len(s)) // 预分配容量,提升性能
var prev rune
for i, r := range s {
if i == 0 || r != prev {
result = append(result, r)
}
prev = r
}
return string(result)
}
✅ 示例验证:
fmt.Println(Squeeze("yellow moon")) // "yelow mon"
fmt.Println(Squeeze(" now is the")) // " now is the"(注意首空格保留)
fmt.Println(Squeeze("??abc??")) // "?abc?"
⚠️ 注意事项:
- 该实现默认对所有连续重复字符生效,不区分 ASCII 或 Unicode;
- 若需模拟 Ruby 中带参数的
squeeze("m-z")(仅压缩指定字符范围内的连续重复),需额外扩展:先构建目标字符集合(如通过strings.ContainsRune或预生成map[rune]bool),再在循环中判断当前rune是否属于该集合,仅对该集合内的连续重复执行压缩; - 空字符串和单字符字符串已做边界处理,确保健壮性;
- 使用
make([]rune, 0, len(s))预估容量,避免频繁切片扩容,对长字符串更友好。
总结:Go 虽无开箱即用的 squeeze,但凭借其显式字符处理模型与简洁的迭代逻辑,可写出语义准确、Unicode 安全、性能可控的等效实现——这正是 Go “少即是多”哲学的典型体现。










