PHP去重字符串应保留首次出现字符,推荐用str_split()+array_unique()+implode()实现;需区分大小写时先转小写判断但保留原大小写;可预过滤空白符,超长字符串宜用for循环提升性能。

PHP 中去除字符串中重复字符,核心思路是保留每个字符首次出现的位置,后续重复的直接跳过。关键在于区分“去重”目标:是去重整个字符串(如 "aabbcc" → "abc"),还是统计后只留唯一字符(不考虑顺序)。
按首次出现顺序去重(推荐)
最常用场景:保持原字符串字符顺序,仅删除后续重复项。用 array_keys() + array_unique() 配合 str_split() 和 implode() 最简洁:
$str = "hello world";-
$chars = str_split($str);—— 拆成字符数组 -
$unique = array_values(array_unique($chars));—— 去重并重排索引 -
$result = implode('', $unique);—— 合并为字符串,结果为"helo wrd"
注意:array_unique() 默认比较值,对字符串数组天然适用;array_values() 是为了确保索引连续,避免 implode 出问题。
区分大小写与空白符处理
默认方案区分大小写和空白符。如需忽略大小写,先统一转小写再处理,但要注意最终结果应保留首次出现的原始大小写:
立即学习“PHP免费学习笔记(深入)”;
- 用
array_reduce()手动遍历更可控: $seen = [];$result = '';foreach (str_split($str) as $char) {if (!in_array(strtolower($char), array_map('strtolower', $seen))) {$result .= $char;$seen[] = $char;}}
若需过滤空格、换行等,可在 str_split() 后用 array_filter($chars, 'ctype_print') 预处理。
高性能场景:单字节字符串用 for 循环
对超长 ASCII 字符串(如日志清洗),避免数组开销,可用原生循环+关联数组标记:
$seen = [];$result = '';for ($i = 0; $i$char = $str[$i];if (!isset($seen[$char])) {$seen[$char] = true;$result .= $char;}}
此法时间复杂度 O(n),空间 O(k)(k 为不同字符数),比数组函数组合更快,且天然支持单字节字符。
多字节字符串(中文、emoji)注意事项
上述方法在 UTF-8 下对中文或 emoji 可能出错,因为 $str[$i] 和 str_split() 默认按字节切分。必须改用 mb_ 系列函数:
- 用
mb_str_split($str, 1, 'UTF-8')(PHP 7.4+)替代str_split() - 或手动用
mb_substr($str, $i, 1, 'UTF-8')遍历 - 判断是否存在时,键名也须是完整字符,不能用字节截取
例如:mb_internal_encoding('UTF-8'); 开头设好编码,再处理中文字符串 "你好世界你好" → "你好世界"。











