最直接的方法是用for循环遍历比较相邻字符;go无内置函数判断连续重复字符,需手动遍历s[i]与s[i+1],ascii字符可直接[]byte遍历,unicode字符必须转[]rune避免utf-8切分错误。

用 for 循环遍历比较相邻字符最直接
Go 没有内置函数能直接判断“重复连续字符”,strings.Contains 或 strings.Count 都不适用——它们不管字符是否连续。最稳妥的方式是手动遍历,逐个比对 s[i] 和 s[i+1]。
注意:字符串在 Go 中是字节序列,若只处理 ASCII 字符(如 a-z、0-9),直接按 []byte 遍历安全;但含中文、emoji 等 Unicode 字符时,必须转为 []rune,否则可能切在 UTF-8 中间字节,导致 panic 或误判。
示例逻辑:
func hasConsecutiveDup(s string) bool {
r := []rune(s)
for i := 0; i
<h3>正则表达式能一行写完但性能差、边界易错</h3>
<p>用 <code>regexp.MatchString</code> 写成 <code>`(.)\1`</code> 看似简洁,但它会匹配任意两个相同连续字符(包括换行、空格等),且正则引擎启动开销大,不适合高频调用或短字符串场景。</p>
<p>常见陷阱:</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill4918" title="Golang Spf13 Viper"><img
src="https://img.php.cn/upload/skill/000/000/081/179025319165074.jpg" alt="Golang Spf13 Viper" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/skill4918" title="Golang Spf13 Viper" class="overflowclass">Golang Spf13 Viper</a>
<p class="overflowclass">Go 配置库,使用 spf13/viper — 分层优先级(flag > env >file > KV > default),提供 BindPFlag/BindPFlags、SetEnvPrefix + SetEnvKeyReplace 等功能。</p>
</div>
<a rel="nofollow" href="/xiazai/skill4918" title="Golang Spf13 Viper" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
-
`(.)\1`在空字符串或单字符上返回false是对的,但若写成`(.+)\1`就错——+要求至少一个字符,\1又要复用该组,实际变成“重复子串”,不是“连续重复字符” - 没加
^和$不影响结果,因为MatchString找的是子串匹配,不是全匹配 - 正则无法区分字节和 rune,对多字节字符(如 “好好”)仍能正确匹配,但底层仍是按字节跑,极端情况下(如非法 UTF-8)可能行为未定义
用 bytes.Compare 对字节切片做快速短路判断(仅限 ASCII)
如果确定输入全是 ASCII(比如 token、base64、hex 字符串),可跳过 rune 转换,直接操作 []byte,避免内存分配,速度更快。
关键点:
- 用
for i := 0; i ,别写成 <code>i ——后者在空切片时 <code>len(b)-2是负数,会 panic - 不要用
bytes.Equal(b[i:i+1], b[i+1:i+2]),开销远大于直接比较b[i] == b[i+1] - 这个方法在
strings.Builder或bufio.Scanner流式处理中很实用,因为输入常以[]byte形式存在,无需转换
边界情况必须单独验证
长度为 0 或 1 的字符串不可能含连续重复字符,直接返回 false 是最快路径。但很多人在循环里漏掉 len(s) 判断,导致 <code>for 循环条件计算 len(r)-1 时没问题,却让逻辑多走一趟。
真正容易被忽略的是空格、制表符、不可见控制字符:它们也是合法字符,' ' 连续两次算重复,'\t\t' 同样算。如果业务要求忽略空白,得先 strings.TrimSpace 或过滤,但那是语义层的事,不是检测逻辑本身的责任。
还有零宽字符(如 \u200b),它们视觉不可见,但 rune 值不同,不会被判定为重复——这点恰恰是正确的,不该为“看起来一样”而牺牲精确性。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










