PHP如何截取子字符串:substr函数详解
在PHP编程中,字符串处理是一项基础且频繁的操作。其中,从字符串中提取指定部分(即截取子字符串)的需求非常普遍。PHP内置的 substr() 函数正是为此而设计的核心工具。本文将详细介绍 substr() 函数的语法、参数、返回值以及各种使用场景,帮助你掌握这一重要技能。
substr函数语法与参数
substr() 函数用于返回字符串的一部分。其基本语法如下:
string substr ( string $string , int $start [, int $length ] )
该函数接受三个参数:
$string:必需。输入字符串,即需要被截取的原字符串。$start:必需。规定在字符串的何处开始截取。如果
$start是正数,则从字符串开头算起的第$start个字符开始(字符串的起始位置是 0)。如果
$start是负数,则从字符串末尾算起的第$start个字符开始。$length:可选。规定要返回的字符串长度。如果
$length是正数,则返回的字符串将从$start位置开始,最多包含$length个字符。如果
$length是负数,则字符串末尾的$length个字符将会被省略。如果省略
$length,则返回的字符串将从$start位置开始直到字符串的结尾。
基础用法示例
让我们通过几个简单的例子来理解其基本工作方式。
<?php $str = "Hello, World!"; // 从第0个位置(H)开始,截取5个字符 echo substr($str, 0, 5); // 输出:Hello // 从第7个位置(W)开始,截取到末尾 echo substr($str, 7); // 输出:World! // 从倒数第6个字符(W)开始,截取到末尾 echo substr($str, -6); // 输出:World! ?>
使用负数的start和length参数
使用负数参数可以方便地从字符串末尾进行操作,这在处理文件扩展名或特定后缀时非常有用。
<?php $filename = "example.picture.jpg"; // 获取文件扩展名:从最后一个点(.)之后开始截取 $extension = substr($filename, strrpos($filename, '.') + 1); echo $extension; // 输出:jpg // 使用负数start获取扩展名 echo substr($filename, -3); // 输出:jpg // 使用负数length:从第0位开始,截取到倒数第4位(即去掉“.jpg”) echo substr($filename, 0, -4); // 输出:example.picture // 从倒数第10位开始,截取到倒数第4位 echo substr($filename, -10, -4); // 输出:picture ?>
处理多字节字符(中文等UTF-8字符串)
一个非常重要的注意事项是:标准的 substr() 函数是按字节(byte)进行操作的,而不是按字符(character)。这对于单字节编码(如ASCII)的字符串没有问题,但对于多字节编码(如UTF-8)的中文、日文等字符串,直接使用 substr() 会导致乱码或截取错误,因为一个中文字符可能由2-4个字节组成。
错误示例:
<?php $chineseStr = "你好,世界!"; // 错误地按字节截取,可能导致乱码 echo substr($chineseStr, 0, 4); // 输出可能是乱码 ?>
正确解决方案: 使用PHP的多字节字符串扩展函数 mb_substr()。
<?php $chineseStr = "你好,世界!"; // 使用mb_substr按字符安全截取 echo mb_substr($chineseStr, 0, 2, 'UTF-8'); // 输出:你好 echo mb_substr($chineseStr, 3, 2, 'UTF-8'); // 输出:世界 ?>
mb_substr() 的用法与 substr() 类似,但需要额外指定字符串的编码(如'UTF-8')。在使用前,请确保已安装并启用了 mbstring 扩展。
substr函数的返回值与边界情况
理解 substr() 在不同情况下的返回值至关重要,这有助于编写健壮的代码。
如果
$start超出了字符串长度,且为正数,函数将返回FALSE(在PHP 7.1.0之前返回空字符串)。如果提供了
$length参数且长度为0,FALSE或NULL,则返回空字符串。如果
$length的值大于或等于字符串从$start开始的剩余长度,则返回从$start到字符串末尾的所有字符。
<?php $str = "Test"; var_dump(substr($str, 10)); // 在PHP 8+ 输出:string(0) "", 更早版本可能为bool(false) var_dump(substr($str, 0, 0)); // 输出:string(0) "" var_dump(substr($str, 0, 10)); // 输出:string(4) "Test" (长度大于剩余部分,返回全部) ?>
实际应用场景
1. 截取文章摘要
在博客或新闻列表中,经常需要将长文章截断为简短的摘要。
<?php
function getExcerpt($content, $length = 100) {
$stripped = strip_tags($content); // 先去除HTML标签
if (mb_strlen($stripped, 'UTF-8') > $length) {
// 使用mb_substr安全截取,并添加省略号
return mb_substr($stripped, 0, $length, 'UTF-8') . '...';
}
return $stripped;
}
$article = "<p>这是一篇关于PHP编程的详细教程文章,内容非常丰富...</p>";
echo getExcerpt($article, 20); // 输出:这是一篇关于PHP编程的详细教程...
?>2. 隐藏部分手机号或身份证号
出于隐私保护目的,对敏感信息进行部分隐藏。
<?php $phone = '13800138000'; // 显示前3位和后4位,中间用*代替 $hiddenPhone = substr($phone, 0, 3) . '****' . substr($phone, -4); echo $hiddenPhone; // 输出:138****8000 ?>
3. 解析URL路径或文件名
<?php $url = "https://www.ipipp.com/products/item123.html"; // 获取路径中的文件名(不含查询参数) $path = parse_url($url, PHP_URL_PATH); // 获取 /products/item123.html $filename = basename($path); // 获取 item123.html // 使用substr和strrpos获取不含扩展名的文件名 $nameWithoutExt = substr($filename, 0, strrpos($filename, '.')); echo $nameWithoutExt; // 输出:item123 ?>
总结
substr() 函数是PHP字符串处理工具箱中的一把利器。掌握其正负参数的含义,是灵活运用它的关键。同时,务必牢记在处理多字节字符时,应优先使用 mb_substr() 以避免乱码问题。通过结合字符串查找函数如 strpos()、strrpos(),你可以实现更复杂、更精准的字符串截取逻辑,从而应对各种实际开发需求。