substr()是截取末尾字符的首选,支持负数起始位置如substr($str,-3),但对utf-8需用mb_substr;rtrim()用于删除末尾指定字符集;正则preg_replace()适用于条件化删除;chop()已废弃。

用 substr() 截取末尾字符最直接
PHP 里截取字符串末尾几位,substr() 是首选。它支持负数起始位置,写法简洁、语义清晰,且 PHP 5.0+ 全版本兼容。
比如想取末尾 3 个字符:substr($str, -3);想删掉末尾 2 个字符,就取前 strlen($str) - 2 位,即 substr($str, 0, -2)。
- 负数长度参数(如
-2)表示“从末尾往前切掉多少位”,不是“保留多少位”——这点容易反直觉 - 如果字符串长度不足要截的位数(比如
substr("a", -3)),会返回false而非空字符串,务必检查返回值或加?? '' -
substr()按字节操作,对 UTF-8 多字节字符(如中文)可能截断乱码;需处理中文时改用mb_substr($str, -3, null, 'UTF-8')
用 rtrim() 删除末尾指定字符(不是“几位”)
如果你实际想删的是末尾重复出现的某些字符(比如空格、斜杠、换行符),而不是固定数量的字符,rtrim() 才是对的工具。
例如:rtrim($str, " \t\n\r\0\x0B") 会把所有出现在末尾的空白字符全删掉;rtrim($str, "/") 常用于清理 URL 末尾多余的斜杠。
立即学习“PHP免费学习笔记(深入)”;
-
rtrim()是按字符集合匹配,不是按位置,所以rtrim("abcxx", "x")返回"abc",但rtrim("abcxy", "x")还是"abcxy"(因为y不在集合里,匹配中断) - 第二个参数是字符列表,不是子串;想删固定后缀(如
".txt")不能用它,得用preg_replace('/\.txt$/', '', $str)或手动判断substr($str, -4) === '.txt'
用正则 preg_replace() 精确控制删除逻辑
当需求带条件(如“只删末尾连续 2~4 个数字”“删掉末尾带下划线的版本号”),正则最灵活。
常见模式:preg_replace('/\d{2,4}$/', '', $str) 删末尾 2–4 位数字;preg_replace('/_[0-9.]+$/i', '', $str) 删末尾类似 _v1.2.3 的标记。
- 必须加锚点
$,否则会全局替换,不是“末尾” - 性能比
substr()和rtrim()低一到两个数量级,高频调用场景慎用 - 注意 PCRE 默认不支持 Unicode 属性(如
\p{Han}),处理中文后缀建议改用mb_函数组合判断
别踩 chop() 这个过时坑
chop() 是 rtrim() 的别名,PHP 8.0 已标记为废弃,8.4 将彻底移除。代码里看到它,直接替换成 rtrim()。
- 它不接受第三个编码参数,无法安全处理 UTF-8 字符串
- 函数名有误导性——和“剪切”无关,纯属历史遗留命名
- 部分老教程或框架代码还在用,grep 一下项目里有没有
chop(,顺手清理掉
字符串末尾操作看着简单,但字节 vs 字符、精确位数 vs 字符集、静态长度 vs 动态模式——这几个维度一旦混用,bug 就藏在看似正常的输出里。尤其上线后遇到用户昵称、文件名、API 返回值含中文或特殊符号时,最容易暴露。











