Assuming I have a string
$str="0000,1023,1024,1025,1024,1023,1027,1025,1024,1025,0000";
there are three 1024, I want to replace the third with JJJJ, like this :
output :
0000,1023,1024,1025,1024,1023,1027,1025,JJJJ,1025,0000
how to make str_replace can do it
thanks for the help
As your question asks, you want to use str_replace to do this. It's probably not the best option, but here's what you do using that function. Assuming you have no other instances of "JJJJ" throughout the string, you could do this:
$str = "0000,1023,1024,1025,1024,1023,1027,1025,1024,1025,0000";
$str = str_replace('1024','JJJJ',$str,3)
$str = str_replace('JJJJ','1024',$str,2);
Here is what I would do and it should work regardless of values in $str:
function replace_str($str,$search,$replace,$num) {
$pieces = explode(',',$str);
$counter = 0;
foreach($pieces as $key=>$val) {
if($val == $search) {
$counter++;
if($counter == $num) {
$pieces[$key] = $replace;
}
}
}
return implode(',',$pieces);
}
$str="0000,1023,1024,1025,1024,1023,1027,1025,1024,1025,0000";
echo replace_str($str, '1024', 'JJJJ', 3);
I think this is what you are asking in your comment:
function replace_element($str,$search,$replace,$num) {
$num = $num - 1;
$pieces = explode(',',$str);
if($pieces[$num] == $search) {
$pieces[$num] = $replace;
}
return implode(',',$pieces);
}
$str="0000,1023,1024,1025,1024,1023,1027,1025,1024,1025,0000";
echo replace_element($str,'1024','JJJJ',9);
strpos has an offset, detailed here: http://php.net/manual/en/function.strrpos.php
So you want to do the following:
1) strpos with 1024, keep the offset
2) strpos with 1024 starting at offset+1, keep newoffset
3) strpos with 1024 starting at newoffset+1, keep thirdoffset
4) finally, we can use substr to do the replacement - get the string leading up to the third instance of 1024, concatenate it to what you want to replace it with, then get the substr of the rest of the string afterwards and concatenate it to that. http://www.php.net/manual/en/function.substr.php
You can either use strpos() three times to get the position of the third 1024 in your string and then replace it, or you could write a regex to use with preg_replace() that matches the third 1024.
if you want to find the last occurence of your string you can used strrpos
Do it like this:
$newstring = substr_replace($str,'JJJJ', strrpos($str, '1024'), strlen('1024') );
See working demo
Here's a solution with less calls to one and the same function and without having to explode, iterate over the array and implode again.
// replace the first three occurrences
$replaced = str_replace('1024', 'JJJJ', $str, 3);
// now replace the firs two, which you wanted to keep
$final = str_replace('JJJJ', '1024', $replaced, 2);
Related
I'm looking to preg_replace parts of a string only 3 times, however I don't want it to match and replace only the first 3 matches, but rather more varied throughout the entire string. Is this possible?
Example:
$post ['post_content']=preg_replace ('/ pizza /',' pizza ',$post['post_content'],3);
Use something like this (some tweaking might be needed):
$p = $post ['post_content'];
if (preg_match_all('/ pizza /',$p, $matches)) {
$rand = array_rand($matches[0], 2);
foreach($rand as $rand_key) {
$p=replace_num($matches[0][$rand_key], "XXX",$p, $rand_key+1);
}
}
echo $p;
function replace_num($from, $to, $string,$num) {
$pos=-1;
$i=0;
while($pos!==false && $i<$num) {
$pos = strpos($string, $from, $pos+1);
$i++;
}
if ($pos) {
return substr($string, 0, $pos) . str_replace($from, $to, substr($string,$pos, strlen($from))) . substr($string, $pos) ;
}
return $string;
}
I think you could do it. But it will be a multi-step process.
First: Do a preg_match_all() instead of a replace
Second: Do X number of array_rands to get the position of the 'pizza' string and replace one starting at that position (use substring).
I think you'll have to redo the match after each replacement, because the length of the string will change every time.
Don't forget to remove the index that is returned from the array rand so it isn't used twice.
Skip the 4th parameter which is to limit n go thru the manual first
$limit:
The maximum possible replacements for each pattern in each subject string. Defaults to -1 (no limit).
I have a string that looks a little like this, world:region:bash
It divides folder names, so i can create a path for FTP functions.
However, i need at some points to be able to remove the last part of the string, so, for example
I have this world:region:bash
I need to get this world:region
The script wont be able to know what the folder names are, so some how it needs to be able to remove the string after the last colon.
$res=substr($input,0,strrpos($input,':'));
I should probably highlight that strrpos not strpos finds last occurrence of a substring in given string
$tokens = explode(':', $string); // split string on :
array_pop($tokens); // get rid of last element
$newString = implode(':', $tokens); // wrap back
You may want to try something like this:
<?php
$variable = "world:region:bash";
$colpos = strrpos($variable, ":");
$result = substr($variable, 0, $colpos);
echo $result;
?>
Or... if you create a function using this information, you get this:
<?php
function StrRemoveLastPart($string, $delimiter)
{
$lastdelpos = strrpos($string, $delimiter);
$result = substr($string, 0, $lastdelpos);
return $result;
}
$variable = "world:region:bash";
$result = StrRemoveLastPart($variable, ":");
?>
Explode the string, and remove the last element.
If you need the string again, use implode.
$items = array_pop(explode(':', $the_path));
$shotpath = implode(':', $items);
Use regular expression /:[^:]+$/, preg_replace
$s = "world:region:bash";
$p = "/:[^:]+$/";
$r = '';
echo preg_replace($p, $r, $s);
demo
Notice how $ which means string termination, is made use of.
<?php
$string = 'world:region:bash';
$string = implode(':', explode(':', $string, -1));
I have many strings that follow the same convention:
this.is.a.sample
this.is.another.sample.of.it
this.too
What i want to do is isolate the last part. So i want "sample", or "it", or "too".
What is the most efficient way for this to happen. Obviously there are many ways to do this, but which way is best that uses the least resources (CPU and RAM).
$string = "this.is.another.sample.of.it";
$contents = explode('.', $string);
echo end($contents); // displays 'it'
I realise this question is from 2012, but the answers here are all inefficient. There are string functions built into PHP to do this, rather than having to traverse the string and turn it into an array, and then pick the last index, which is a lot of work to do something quite simple.
The following code gets the last occurrence of a string within a string:
strrchr($string, '.'); // Last occurrence of '.' within a string
We can use this in conjunction with substr, which essentially chops a string up based on a position.
$string = 'this.is.a.sample';
$last_section = substr($string, (strrchr($string, '-') + 1));
echo $last_section; // 'sample'
Note the +1 on the strrchr result; this is because strrchr returns the index of the string within the string (starting at position 0), so the true 'position' is always 1 character on.
http://us3.php.net/strpos
$haystack = "this.is.another.sample.of.it";
$needle = "sample";
$string = substr( $haystack, strpos( $haystack, $needle ), strlen( $needle ) );
Just do:
$string = "this.is.another.sample.of.it";
$parts = explode('.', $string);
$last = array_pop(parts);
$new_string = explode(".", "this.is.sparta");
$last_part = $new_string[count($new_string)-1];
echo $last_part; // prints "sparta".
$string = "this.is.another.sample.of.it";
$result = explode('.', $string); // using explode function
print_r($result); // whole Array
Will give you
result[0]=>this;
result[1]=>is;
result[2]=>another;
result[3]=>sample;
result[4]=>of;
result[5]=>it;
Display any one you want (ex. echo result[5];)
I would like to split a string at the first line break, instead of the first blank line
'/^(.*?)\r?\n\r?\n(.*)/s' (first blank line)
So for instance, if I have:
$str = '2099 test\nAre you sure you
want to continue\n some other string
here...';
match[1] = '2099 test'
match[2] = 'Are you sure you want to continue\n some other string here...'
preg_split() has a limit parameter you can take to your advantage. You could just simply do:
$lines = preg_split('/\r\n|\r|\n/', $str, 2);
<?php
$str = "2099 test\nAre you sure you want to continue\n some other string here...";
$match = explode("\n",$str, 2);
print_r($match);
?>
returns
Array
(
[0] => 2099 test
[1] => Are you sure you want to continue
some other string here...
)
explode's last parameter is the number of elements you want to split the string into.
Normally just remove on \r?\n:
'/^(.*?)\r?\n(.*)/s'
You can use preg_split as:
$arr = preg_split("/\r?\n/",$str,2);
See it on Ideone
First line break:
$match = preg_split('/\R/', $str, 2);
First blank line:
$match = preg_split('/\R\R/', $str, 2);
Handles all the various ways of doing line breaks.
Also there was a question about splitting on the 2nd line break. Here is my implementation (maybe not most efficient... also note it replaces some line breaks with PHP_EOL)
function split_at_nth_line_break($str, $n = 1) {
$match = preg_split('/\R/', $str, $n+1);
if (count($match) === $n+1) {
$rest = array_pop($match);
}
$match = array(implode(PHP_EOL, $match));
if (isset($rest)) {
$match[] = $rest;
}
return $match;
}
$match = split_at_nth_line_break($str, 2);
Maybe you don't even need to use regex's. To get just split lines, see:
What's the simplest way to return the first line of a multi-line string in Perl?
I am trying to extract a substring. I need some help with doing it in PHP.
Here are some sample strings I am working with and the results I need:
home/cat1/subcat2 => home
test/cat2 => test
startpage => startpage
I want to get the string till the first /, but if no / is present, get the whole string.
I tried,
substr($mystring, 0, strpos($mystring, '/'))
I think it says - get the position of / and then get the substring from position 0 to that position.
I don't know how to handle the case where there is no /, without making the statement too big.
Is there a way to handle that case also without making the PHP statement too complex?
The most efficient solution is the strtok function:
strtok($mystring, '/')
NOTE: In case of more than one character to split with the results may not meet your expectations e.g. strtok("somethingtosplit", "to") returns s because it is splitting by any single character from the second argument (in this case o is used).
#friek108 thanks for pointing that out in your comment.
For example:
$mystring = 'home/cat1/subcat2/';
$first = strtok($mystring, '/');
echo $first; // home
and
$mystring = 'home';
$first = strtok($mystring, '/');
echo $first; // home
Use explode()
$arr = explode("/", $string, 2);
$first = $arr[0];
In this case, I'm using the limit parameter to explode so that php won't scan the string any more than what's needed.
$first = explode("/", $string)[0];
What about this :
substr($mystring.'/', 0, strpos($mystring, '/'))
Simply add a '/' to the end of mystring so you can be sure there is at least one ;)
Late is better than never. php has a predefined function for that. here is that good way.
strstr
if you want to get the part before match just set before_needle (3rd parameter) to true
http://php.net/manual/en/function.strstr.php
function not_strtok($string, $delimiter)
{
$buffer = strstr($string, $delimiter, true);
if (false === $buffer) {
return $string;
}
return $buffer;
}
var_dump(
not_strtok('st/art/page', '/')
);
One-line version of the accepted answer:
$out=explode("/", $mystring, 2)[0];
Should work in php 5.4+
This is probably the shortest example that came to my mind:
list($first) = explode("/", $mystring);
1) list() will automatically assign string until "/" if delimiter is found
2) if delimiter "/"is not found then the whole string will be assigned
...and if you get really obsessed with performance, you may add extra parameter to explode explode("/", $mystring, 2) which limits maximum of the returned elements.
The function strstr() in PHP 5.3 should do this job.. The third parameter however should be set to true..
But if you're not using 5.3, then the function below should work accurately:
function strbstr( $str, $char, $start=0 ){
if ( isset($str[ $start ]) && $str[$start]!=$char ){
return $str[$start].strbstr( $str, $char, $start+1 );
}
}
I haven't tested it though, but this should work just fine.. And it's pretty fast as well
You can try using a regex like this:
$s = preg_replace('|/.*$|', '', $s);
sometimes, regex are slower though, so if performance is an issue, make sure to benchmark this properly and use an other alternative with substrings if it's more suitable for you.
Using current on explode would ease the process.
$str = current(explode("/", $str, 2));
You could create a helper function to take care of that:
/**
* Return string before needle if it exists.
*
* #param string $str
* #param mixed $needle
* #return string
*/
function str_before($str, $needle)
{
$pos = strpos($str, $needle);
return ($pos !== false) ? substr($str, 0, $pos) : $str;
}
Here's a use case:
$sing = 'My name is Luka. I live on the second floor.';
echo str_before($sing, '.'); // My name is Luka
$arr = explode("/", $string, 2); $first = $arr[0];
This Way is better and more accurate than strtok
because if you wanna get the values before # for example
while the there's no string before # it will give you whats after the sign .
but explode doesnt
$string="kalion/home/public_html";
$newstring=( stristr($string,"/")==FALSE ) ? $string : substr($string,0,stripos($string,"/"));
why not use:
function getwhatiwant($s)
{
$delimiter='/';
$x=strstr($s,$delimiter,true);
return ($x?$x:$s);
}
OR:
function getwhatiwant($s)
{
$delimiter='/';
$t=explode($delimiter, $s);
return ($t[1]?$t[0]:$s);
}