I am trying to get 2 words from a string, where the 2 words can be different each time.
In this example, I'm trying to get Open and On Hold
$str = 'Status Changed from Open to On Hold';
I've managed to get Open with this code:
$starting_word = 'Status Changed from';
$ending_word = 'to';
$subtring_start = strpos($str, $starting_word).strlen($starting_word);
$size = strpos($str, $ending_word, $subtring_start) - $subtring_start;
$a = substr($str, $subtring_start, $size);
And then I tried to get On Hold using this, but it's returning nothing.
$subtring_start = strpos($str, $a);
$size = strpos($str, '', $subtring_start) - $subtring_start;
$b = substr($str, $subtring_start, $size);
echo $b;
You'll get some good answers on how to do it similar to your approach, but this is easier:
preg_match('/ from ([^ ]+) to (.*)/', $str, $matches);
echo $matches[1];
echo $matches[2];
match a space and from and a space
capture () anything not a space [^ ]+ up to a space and to
capture () anything .* to the end
Even though you haven't made clear what the specific dynamic words are, but you can try the following code to get the second string, that is, in your case, 'On Hold'.
$str = 'Status Changed from Open to On Hold';
$starting_word = 'Status Changed from';
$ending_word = 'to';
$size = strpos($str, $ending_word);
$second_value = substr($str, $size+3);
echo $second_value;
Output:
On Hold
Try and change the 'On Hold' in your $str and run the code again, and see the magic.
Try it online!
This question already has answers here:
How to remove part of a string after last comma in PHP
(3 answers)
Closed 3 years ago.
I would like to remove the last hyphen and anything after it in a string. After looking I found something that does the first hyphen but not last:
$str = 'sdfsdf-sdfsdf-abcde';
$str = array_shift(explode('-', $str));
Current String
$str = 'sdfsdf-sdfsdf-abcde';
Desired Result
$str = 'sdfsdf-sdfsdf';
You can use this preg_replace:
$repl = preg_replace('/-[^-]*$/', '', $str);
//=> sdfsdf-sdfsdf
-[^-]*$ will match - followed by 0 or more non-hyphen characters before end of line.
You can use strrpos to get the last index, and then use substr to get the desired result.
$str = 'sdfsdf-sdfsdf-abcde';
$pos = strrpos($str , "-");
if ($pos !== false) {
echo substr($str, 0, $pos);
}
You're close. Just use array_pop() instead of array_shift(). array_pop() removes last element of array. You need, of course, use implode() later to put the strign together again.
$arr = explode('-', $str);
array_pop($arr);
$str = implode('-', $arr);
It's important not to do that in one line since array_pop() works on a reference to the array and it modfies it, and then returns only removed element.
There are a few other possible solutions mentions by other answers.
This is a little bulky but it will work for you:
$str = 'sdfsdf-sdfsdf-abcde';
$pieces = explode("-",$str);
$count = count($pieces);
for ($x = 0; $x <= $count - 2; $x++) {
$desired_result .= $pieces[$x].'-';
}
$desired_result = substr($desired_result, 0, -1);
echo $desired_result;
if you have a lot of them you can use this function:
function removeLast($str){
$pieces = explode("-",$str);
$count = count($pieces);
for ($x = 0; $x <= $count - 2; $x++) {
$desired_result .= $pieces[$x].'-';
}
$desired_result = substr($desired_result, 0, -1);
return $desired_result;
}
you call it by:
$str = 'sdfsdf-sdfsdf-abcde';
$my_result = removeLast($str);
In strpos function we can define offset - where parser sholud start search our substring in string. I have to create something similar - I have to remove range offsets from string, for exacly:
$string = 'This is my string';
echo strpos($string, 'is my', 0);
and it will be return something position of substring is my in main $string.
But how to tell a PHP script to search in all string (like this script above) but not in position from X to Y? Is it possible?
Note:
I'm using mb_strpos() but I think, a solution will be very similar for both functions.
Thanks.
You need your custom function - that should work for you:
//$X<$Y
funciton getOffset($str, $needle, $X, $Y) {
$str1 = substr($str, 0, $X);
$str2 = substr($str, $Y);
$pos1 = strpos($str1, $needle, 0);
$pos2 = $Y + strpos($str1, 'is my', 0);
return false == $pos1 ? $pos2 : $pos1;
}
I have a string
$str = "[xyz.hlp] into asasa jkljk [xyp.htq] zff [xrt.thg]";
I want to get the character from the string and make an array of all those characters . for example for the above string provided I shuould get and array like this
$array("xyz.hlp","xyp.htq","xrt.thg");
I tried using preg_match(); something like this but it didn't work
preg_match('/\[(.*)\]/', $str , $Fdesc);
Thanks in Advance
I got the desired output but by using loop and some php string functions
<?php
$str = "[xyz.hlp] into asasa jkljk [xyp.htq] zff [xrt.thg]";
$i = 0;
while ($i != strrpos($str, "]")) {
$f_pos = strpos($str, "[", $i); // for first position
$l_pos = strpos($str, "]", $f_pos + 1); // for the last position
$value = substr($str, $f_pos, ($l_pos - $f_pos) + 1);
echo $value;
$i = $l_pos;
}
?>
$split_point = ' - ';
$string = 'this is my - string - and more';
How can I make a split using the second instance of $split_point and not the first one. Can I specify somehow a right to left search?
Basically how do I explode from right to left. I want to pick up only the last instance of " - ".
Result I need:
$item[0]='this is my - string';
$item[1]='and more';
and not:
$item[0]='this is my';
$item[1]='string - and more';
You may use strrev to reverse the string, and then reverse the results back:
$split_point = ' - ';
$string = 'this is my - string - and more';
$result = array_map('strrev', explode($split_point, strrev($string)));
Not sure if this is the best solution though.
How about this:
$parts = explode($split_point, $string);
$last = array_pop($parts);
$item = array(implode($split_point, $parts), $last);
Not going to win any golf awards, but it shows intent and works well, I think.
Here is another way of doing it:
$split_point = ' - ';
$string = 'this is my - string - and more';
$stringpos = strrpos($string, $split_point, -1);
$finalstr = substr($string,0,$stringpos);
If I understand correctly, you want the example case to give you ('this is my - string', 'and more')?
Built-in split/explode seems to be forwards-only - you'll probably have to implement it yourself with strrpos. (right-left search)
$idx = strrpos($string, $split_point);
$parts = array(substr($string, 0, $idx), substr($string, $idx+strlen($split_point)))
Why not split on ' - ', but then join the first two array entries that you get back together?
I've stumbled uppon the same, and fixed it like so:
$split_point = ' - ';
$string = 'this is my - string - and more';
$reverse_explode = array_reverse(explode($split_point, $string));
I liked Moff's answer, but I improved it by limiting the number of elements to 2 and re-reversing the array:
$split_point = ' - ';
$string = 'this is my - string - and more';
$result = array_reverse(array_map('strrev', explode($split_point, strrev($string),2)));
Then $result will be :
Array ( [0] => this is my - string [1] => and more )
this is my - string - and more
Use common explode function to get all strings
Get sizeof array and fetch last item
Pop last item using array_pop function.
Implode remaining string with same delimeter(if u want other delimeter can use).
Code
$arrSpits=explode("", "this is my - string - and more");
$arrSize=count($arrSpits);
echo "Last string".$arrSpits[arrSize-1];//Output: and more
array_pop(arrSpits); //now pop the last element from array
$firstString=implode("-", arrSpits);
echo "First String".firstString; //Output: this is my - string
I am underwhelmed by all of the over-engineered answers which are calling many functions and/or iterating over data multiple times. All of those string and array reversing functions make the technique very hard to comprehend.
Regex is powerfully elegant in this case. This is exactly how I would do it in a professional application:
Code: (Demo)
$string = 'this is my - string - and more';
var_export(preg_split('~.*\K - ~', $string));
Output:
array (
0 => 'this is my - string',
1 => 'and more',
)
By greedily matching characters (.*), then restarting the fullstring match (\K), then matching the last occurring delimiting substring (" - "), you are assured to only separate the final substring from the string.
Assuming you only want the first occurrence of $split_point to be ignored, this should work for you:
# retrieve first $split_point position
$first = strpos($string, $split_point);
# retrieve second $split_point positon
$second = strpos($string, $split_point, $first+strlen($split_point));
# extract from the second $split_point onwards (with $split_point)
$substr = substr($string, $second);
# explode $substr, first element should be empty
$array = explode($split_point, $substr);
# set first element as beginning of string to the second $split_point
$array[0] = substr_replace($string, '', strpos($string, $substr));
This will allow you to split on every occurrence of $split_point after (and including) the second occurrence of $split_point.
Just an idea:
function explode_reversed($delim,$s){
$result = array();
$w = "";
$l = 0;
for ($i = strlen($s)-1; $i>=0; $i-- ):
if ( $s[$i] == "$delim" ):
$l++;
$w = "";
else:
$w = $s[$i].$w;
endif;
$result[$l] = $w;
endfor;
return $result;
}
$arr = explode_reversed(" ","Hello! My name is John.");
print_r($arr);
Result:
Array
(
[0] => John.
[1] => is
[2] => name
[3] => My
[4] => Hello!
)
But this is much slower then explode. A test made:
$start_time = microtime(true);
for ($i=0; $i<1000;$i++)
$arr = explode_reversed(" ","Hello! My name is John.");
$time_elapsed_secs = microtime(true) - $start_time;
echo "time: $time_elapsed_secs s<br>";
Takes 0.0625 - 0.078125s
But
for ($i=0; $i<1000;$i++)
$arr = explode(" ","Hello! My name is John.");
Takes just 0.015625s
The fastest solution seems to be:
array_reverse(explode($your_delimiter, $your_string));
In a loop of 1000 times this is the best time I can get 0.03125s.
Not sure why no one posted a working function with $limit support though here it is for those who know that they'll be using this frequently:
<?php
function explode_right($boundary, $string, $limit)
{
return array_reverse(array_map('strrev', explode(strrev($boundary), strrev($string), $limit)));
}
$string = 'apple1orange1banana1cupuacu1cherimoya1mangosteen1durian';
echo $string.'<br /><pre>'.print_r(explode_right(1, $string, 3),1).'</pre>';
?>
$split_point = ' - ';
$string = 'this is my - string - and more';
$result = end(explode($split_point, $string));
This is working fine