I need to split a string in PHP by "-" and get the last part.
So from this:
abc-123-xyz-789
I expect to get
"789"
This is the code I've come up with:
substr(strrchr($urlId, '-'), 1)
which works fine, except:
If my input-string does not contain any "-", I must get the whole string, like from:
123
I need to get back
123
and it needs to be as fast as possible. Any help is appreciated!
You can do it like this:
$str = "abc-123-xyz-789";
$last = array_pop( explode('-', $str) );
echo $last; //echoes 789
You can use array_pop combined with explode
Code:
$string = 'abc-123-xyz-789';
$output = array_pop(explode("-",$string));
echo $output;
DEMO: Click here
As has been mentioned by others, if you don't assign the result of explode()
to a variable, you get the message:
E_STRICT: Strict standards: Only variables should be passed by reference
The correct way is:
$words = explode('-', 'hello-world-123');
$id = array_pop($words); // 123
$slug = implode('-', $words); // hello-world
To satisfy the requirement that "it needs to be as fast as possible" I ran a benchmark against some possible solutions. Each solution had to satisfy this set of test cases.
$cases = [
'aaa-zzz' => 'zzz',
'zzz' => 'zzz',
'-zzz' => 'zzz',
'aaa-' => '',
'' => '',
'aaa-bbb-ccc-ddd-eee-fff-zzz' => 'zzz',
];
Here are the solutions:
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);
}
Here are the results after each solution was run against the test cases 1,000,000 times:
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%
So turns out the fastest of these was using substr
with strpos
. Note that in this solution we must check strpos
for false
so we can return the full string (catering for the zzz
case).
Just check whether or not the delimiting character exists, and either split or don't:
if (strpos($potentiallyDelimitedString, '-') !== FALSE) {
found delimiter, so split
}
$string = 'abc-123-xyz-789';
$exploded = explode('-', $string);
echo end($exploded);
EDIT::Finally got around to removing the E_STRICT issue
You can do it like this:
$str = "abc-123-xyz-789";
$arr = explode('-', $str);
$last = array_pop( $arr );
echo $last; //echoes 789
As per this post:
end((explode('-', $string)));
which won't cause E_STRICT warning in PHP 5 (PHP magic). Although the warning will be issued in PHP 7, so adding @
in front of it can be used as a workaround.
Just Call the following single line code:
$expectedString = end(explode('-', $orignalString));
The accepted answer has a bug in it where it still eats the first character of the input string if the delimiter is not found.
$str = '1-2-3-4-5';
echo substr($str, strrpos($str, '-') + 1);
Produces the expected result: 5
$str = '1-2-3-4-5';
echo substr($str, strrpos($str, ';') + 1);
Produces -2-3-4-5
$str = '1-2-3-4-5';
if (($pos = strrpos($str, ';')) !== false)
echo substr($str, $pos + 1);
else
echo $str;
Produces the whole string as desired.
Since explode()
returns an array, you can add square brackets directly to the end of that function, if you happen to know the position of the last array item.
$email = '[email protected]';
$provider = explode('@', $email)[1];
echo $provider; // example.com
Or another way is list()
:
$email = '[email protected]';
list($prefix, $provider) = explode('@', $email);
echo $provider; // example.com
If you don't know the position:
$path = 'one/two/three/four';
$dirs = explode('/', $path);
$last_dir = $dirs[count($dirs) - 1];
echo $last_dir; // four
This code will do that
<?php
$string = 'abc-123-xyz-789';
$output = explode("-",$string);
echo $output[count($output)-1];
?>
Source: Stackoverflow.com