PHP去除字符串中重复字符的几种实现方法
在处理包含汉字的字符串时,直接使用 strlen 或 substr 会导致乱码或截断错误。针对 PHP 去除字符串中的重复字符(尤其是多字节中文),可以采用基于 mb_* 函数的遍历法、自定义 UTF-8 分割结合数组去重法,或利用内置的正则表达式进行匹配替换。
核心问题分析
普通英文字符串可以使用 str_split() 轻松拆分,但中文等多字节字符若按单字节截取,会破坏 UTF-8 编码结构,导致后续去重逻辑失效或输出乱码。因此,必须使用支持多字节安全的函数或手动解析字节流。
方法一:利用 mb_系列函数与数组索引过滤
这是最直观且代码量较少的方案。原理是遍历字符串中的每个字符,使用关联数组作为“哈希表”来记录字符是否已经出现过。
第1步:初始化变量
定义原始文本和用于存储结果的空字符串及过滤数组。注意设置正确的字符编码为 utf-8。
第2步:遍历并去重
获取字符串长度,循环提取每个字符。检查该字符是否在过滤数组中存在,若不存在则追加到结果字符串,并在过滤数组中标记为已存在。
代码如下:
$text = '数组aabbccdd';
$text_filter = '';
$filter = array();
$len = mb_strlen($text, 'utf-8');
for ($i = 0; $i < $len; $i++) {
$char = mb_substr($text, $i, 1, 'utf-8');
if (!isset($filter[$char])) {
$text_filter .= $char;
$filter[$char] = true; // 标记已存在
}
}
echo $text_filter; // 输出: 数组abcd
关键点: mb_strlen 返回的是字符数而非字节数,mb_substr 按字符位置截取,确保中文不被拆分。
方法二:自定义 UTF-8 分割函数配合 array_unique
如果不想修改主逻辑,可以封装一个专门将 UTF-8 字符串拆分为字符数组的函数,然后复用 PHP 内置的 array_unique() 进行去重。
第1步:构建字符拆分辅助函数
通过检测字节的 ASCII 值判断当前字符占用几个字节(1~4字节),从而安全地将多字节字符串切分为单元数组。
代码如下:
$string = '数组aabbccdd';
function str_split_utf8($str) {
$split = 1;
$array = array();
for ($i = 0; $i < strlen($str); ) {
$value = ord($str[$i]);
// 判断字节长度
if ($value > 127) {
if ($value >= 192 && $value <= 223) $split = 2;
elseif ($value >= 224 && $value <= 239) $split = 3;
elseif ($value >= 240 && $value <= 247) $split = 4;
} else {
$split = 1;
}
$key = NULL;
for ($j = 0; $j < $split; $j++, $i++) {
$key .= $str[$i];
}
array_push($array, $key);
}
return $array;
}
第2步:执行去重并输出
调用上述函数获取字符数组,传入 array_unique() 去除重复元素,最后可使用 implode() 还原为字符串。
代码如下:
// 拆分
$chars = str_split_utf8($string);
// 去重
$unique_chars = array_unique($chars);
// 可选:重新组合成字符串
$result = implode('', $unique_chars);
print_r($result); // 输出: Array ( [0] => 数组 [1] => a [2] => b [3] => c [4] => d ) 或拼接后的字符串
方法对比与建议
- 性能: 方法一在循环中进行字符串拼接,对于超长字符串可能产生较多内存开销;方法二先拆分成数组再处理,内存占用相对可控,但代码复杂度较高。
- 简洁性: 方法一代码更短,易于理解,适合大多数场景。
- 注意事项: 原文提到的“方法三”仅描述思路(分割后使用
array_unique),未提供具体实现,实际上与方法二的后半部分逻辑一致,无需单独作为独立技术方案。
以上就是PHP去除重复字符的详细内容,更多关于PHP字符串处理技巧的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









