PHP mb_str_split 如何保留分隔符并控制偏移
来源:17golang原创
时间:2026-09-14 11:32:34 164浏览 收藏
我第一次在接口里处理“中文标题,按第几个字符开始,再把逗号保留”的需求时,差点把 mb_str_split() 当成了带 separator 和 offset 的增强版 explode()。实际签名只有字符串、每块字符数和编码三个参数。要控制起点,先用 mb_substr();要保留分隔符,再用带捕获组的 preg_split()。这样中文、英文和 emoji 的位置都按字符处理。
官方手册:https://www.php.net/manual/en/function.mb-str-split.php
mb_str_split()的length是字符数,不是字节数,不能直接传分隔符或偏移量。- 从第 N 个字符开始处理,用
mb_substr($text, $offset, null, 'UTF-8'),偏移从 0 开始。 - 保留分隔符,用
preg_split()的捕获组和PREG_SPLIT_DELIM_CAPTURE,再明确连续分隔符是否保留空项。
mb_str_split 先做字符级切分,但它没有 offset 和 separator
如果目标只是把多字节字符串按字符或固定字符数切块,mb_str_split($text, 2, 'UTF-8') 就够了。第三个参数建议显式写出,避免调用方依赖运行时的内部编码。它返回的是字符块数组,不会理解“逗号是分隔符”,也不会从指定偏移开始。

这里的 2 表示两个字符,不是两个字节。若输入包含中文,改用 str_split() 会把 UTF-8 字节拆开,后续输出可能出现乱码。
按字符偏移开始处理,先截取再切分
“从第 5 个字符开始”与“找到第二个逗号后开始”是两种不同需求。前者可直接使用 mb_substr();后者先用 mb_strpos() 查到字符位置,再把位置交给 mb_substr()。这两个函数的坐标都是字符坐标,不能和 strlen() 或 strpos() 的字节坐标混用。
偏移点恰好落在分隔符上时,要先定规则:是把这个分隔符算进结果,还是从它后面的内容开始。对日志、标签和订单备注,我通常让偏移先截取,再做分隔符拆分,规则最容易复现。
用 preg_split 捕获分隔符,再决定是否过滤空项
preg_split() 默认会丢掉匹配到的分隔符;把分隔符放进正则捕获组,并传入 PREG_SPLIT_DELIM_CAPTURE 后,分隔符会按原样成为数组元素。中文逗号、英文逗号可以放在同一个字符类里,正则末尾的 u 表示按 UTF-8 处理。

PREG_SPLIT_NO_EMPTY 会过滤空字符串。若文本可能出现连续分隔符,先去掉这个标志并在业务层保留空项,才能区分“两个分隔符之间确实没有内容”和“输入尾部多了一个分隔符”。
把偏移与分隔符策略封装成一个小接口
如果调用处反复出现“先截取、再拆分”,可以封装成一个函数。它不伪装成 mb_str_split() 的新参数,而是明确说明:offset 是字符下标,delimiter 是字面分隔符,返回数组包含内容和分隔符。
| 需求 | 合适函数 | 关键边界 |
|---|---|---|
| 按字符定长切块 | mb_str_split | length 大于 0,按字符计数 |
| 从字符位置开始 | mb_substr | offset 从 0 开始,可为负 |
| 查找多字节分隔符 | mb_strpos | 未找到返回 false |
| 保留分隔符 | preg_split | 捕获组加 PREG_SPLIT_DELIM_CAPTURE |
相关问题
mb_str_split 能直接传 offset 吗?
不能。它的第二个参数是每块的字符长度,不是起始位置;先用 mb_substr() 截取剩余字符串。
为什么结果里的中文分隔符消失了?
因为 preg_split() 默认移除匹配内容。使用捕获组和 PREG_SPLIT_DELIM_CAPTURE 才会把分隔符放回数组。
emoji 能按一个字符处理吗?
mb_* 函数按 Unicode 代码点处理,并不等于用户感知的完整字形;需要按字素簇切分时,应另行评估 grapheme_* 系列函数。
-
文章 · php教程 | 11分钟前 | php教程 · 日期处理 · DatePeriod · 时间区间 · 参数语义 · PHP DatePeriod DatePeriod INCLUDE_END_DATE PHP 日期区间结束日期 PHP 日期周期边界 DatePeriod recurrences355 收藏
-
439 收藏
-
157 收藏
-
216 收藏
-
文章 · php教程 | 23小时前 | PHP · 文件流 · 故障排查 · stream_copy_to_stream · 文件复制 短写 stream_copy_to_stream PHP流 流位置123 收藏
-
121 收藏
-
472 收藏
-
104 收藏
-
205 收藏
-
498 收藏
-
157 收藏
-
363 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习