在PHP中分割字符串并获取最后一部分

60

我需要在 PHP 中按照“ - ”拆分字符串并获取最后一部分。

因此从这个字符串:

abc-123-xyz-789

我期望得到:

"789"

这是我想出来的代码:

substr(strrchr($urlId, '-'), 1)

这个功能很好,但是:

如果我的输入字符串中不包含任何“-”,我必须获取整个字符串,例如从:

123

我需要得到:

123

而且需要尽可能快。


4
explode()函数用于将一个字符串通过指定的分隔符进行分割成数组,返回包含分割后的子串的数组。end()函数用于获取数组中的最后一个元素。 - Wrikken
1
end(split('-',$str)) - Wesley Schleumer de Góes
https://dev59.com/ZmAf5IYBdhLWcg3wnDsI - mickmackusa
16个回答

155
  • preg_split($pattern,$string)函数可以根据给定的正则表达式模式来拆分字符串。
  • explode($pattern,$string)函数可以根据给定的模式来拆分字符串。
  • end($arr)函数可以获取数组的最后一个元素。

因此:

$strArray = explode('-',$str)
$lastElement = end(explode('-', $strArray));
// or
$lastElement = end(preg_split('/-/', $str));

将返回由-分隔的字符串的最后一个元素。


还有一种高级方法可以实现这个功能:

$str = '1-2-3-4-5';
echo substr($str, strrpos($str, '-') + 1);
//      |            '--- get the last position of '-' and add 1(if don't substr will get '-' too)
//      '----- get the last piece of string after the last occurrence of '-'

3
array_pop 函数将删除数组中的最后一个元素并返回该元素,而 end 函数仅返回最后一个元素。我认为它们在性能方面没有区别。 - Wesley Schleumer de Góes
1
@Skarlinski 如果不必要的话,最快的方法就是不要出错。 - Grant Thomas
6
“split”不是已经被弃用了吗? - Raphael Jeger
更新了答案,列出了所有可能的(正确)方法。我进行了研究,explode理论上比split更快。 - Wesley Schleumer de Góes
41
end(explode('-',$str)) 出现错误:Strict (2048): Only variables should be passed by reference。解决方法请参考:https://dev59.com/3m445IYBdhLWcg3w6eXz。 - trante
显示剩余5条评论

29
$string = 'abc-123-xyz-789';
$exploded = explode('-', $string);
echo end($exploded);

这个没有 E_STRICT 问题。


11
它会导致 E_STRICT 错误:Strict standards: Only variables should be passed by reference. - Alexey Kosov

7
只需检查分隔字符是否存在,然后确定是拆分还是不拆分:
if (strpos($potentiallyDelimitedString, '-') !== FALSE) {
  found delimiter, so split
}

6
为了满足“尽可能快”的要求,我对一些可能的解决方案进行了基准测试。每个解决方案都必须满足这组测试用例。
$cases = [
    'aaa-zzz'                     => 'zzz',
    'zzz'                         => 'zzz',
    '-zzz'                        => 'zzz',
    'aaa-'                        => '',
    ''                            => '',
    'aaa-bbb-ccc-ddd-eee-fff-zzz' => 'zzz',
];

以下是解决方案:
function test_substr($str, $delimiter = '-') {
    $idx = strrpos($str, $delimiter);
    return $idx === false ? $str : substr($str, $idx + 1);
}

function test_end_index($str, $delimiter = '-') {
    $arr = explode($delimiter, $str);
    return $arr[count($arr) - 1];
}

function test_end_explode($str, $delimiter = '-') {
    $arr = explode($delimiter, $str);
    return end($arr);
}

function test_end_preg_split($str, $pattern = '/-/') {
    $arr = preg_split($pattern, $str);
    return end($arr);
}

以下是每种解决方案针对100万次测试用例运行后的结果:
test_substr               : 1.706 sec
test_end_index            : 2.131 sec  +0.425 sec  +25%
test_end_explode          : 2.199 sec  +0.493 sec  +29%
test_end_preg_split       : 2.775 sec  +1.069 sec  +63%

事实证明,使用substrstrpos是最快的方法。请注意,在这个解决方案中,我们必须检查strpos是否为false,以便返回完整的字符串(适用于zzz情况)。


4
array_reverse(explode('-', $str))[0]

3

6
魔术功能已经在php7中消失了。点击链接查看有关变量处理方面的不兼容信息:http://php.net/manual/zh/migration70.incompatible.php#migration70.incompatible.variable-handling.parentheses - mpapec

3
这段代码将实现该功能。
<?php
$string = 'abc-123-xyz-789';
$output = explode("-",$string);
echo $output[count($output)-1];
?>

2

正如其他人所提到的,如果你不将explode()的结果分配给一个变量,你会得到以下消息:

E_STRICT: Strict standards: Only variables should be passed by reference

正确的方式是:

$words = explode('-', 'hello-world-123');
$id = array_pop($words); // 123
$slug = implode('-', $words); // hello-world

0

由于explode()返回一个数组,如果您知道最后一个数组项的位置,可以直接在该函数的末尾添加方括号。

$email = 'name@example.com';
$provider = explode('@', $email)[1];
echo $provider; // example.com

另一种方法是使用list()

$email = 'name@example.com';
list($prefix, $provider) = explode('@', $email);
echo $provider; // example.com

如果您不知道位置:

$path = 'one/two/three/four';
$dirs = explode('/', $path);
$last_dir = $dirs[count($dirs) - 1];
echo $last_dir; // four

0

这个解决方案是空值安全的,并支持所有的PHP版本:

// https://www.php.net/manual/en/function.array-slice.php
$strLastStringToken = array_slice(explode('-',$str),-1,1)[0];

如果 $str = null,则返回 ''


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接