PHP substr after a certain char, a substr + strpos elegant solution?
Asked Answered
C

5

20

let's say I want to return all chars after some needle char 'x' from:

$source_str = "Tuex helo babe".

Normally I would do this:

if( ($x_pos = strpos($source_str, 'x')) !== FALSE )
   $source_str = substr($source_str, $x_pos + 1);

Do you know a better/smarter (more elegant way) to do this?

Without using regexp that would not make it more elegant and probably also slower.

Unfortunately we can not do:

$source_str = substr(source_str, strpos(source_str, 'x') + 1);

Because when 'x' is not found strpos returns FALSE (and not -1 like in JS). FALSE would evaluate to zero, and 1st char would be always cut off.

Thanks,

Campbell answered 27/10, 2010 at 17:41 Comment(5)
Use your first approach.Rianna
couldn't you remove the "!== FALSE" and this way it will be a little more compact?Tonus
@Gumbo, I'm afraid you are right. Plz write it down as an answer, and I choose yours, unless something better comes out.Campbell
You could force the FALSE to a 0 with 'intval': $source_str=substr($source_str,intval(strpos($source_str,'x'))+1);Superconductivity
@patrick: why would I need to force FALSE into 0? FALSE is already converted to zero by PHP.Campbell
R
14

Your first approach is fine: Check whether x is contained with strpos and if so get anything after it with substr.

But you could also use strstr:

strstr($str, 'x')

But as this returns the substring beginning with x, use substr to get the part after x:

if (($tmp = strstr($str, 'x')) !== false) {
    $str = substr($tmp, 1);
}

But this is far more complicated. So use your strpos approach instead.

Rianna answered 27/10, 2010 at 17:45 Comment(2)
But strstr return FALSE if needle is not found, not the entire string.Campbell
from PHP 5.3+ strstr() accepts an optional third parameter 'before_needle' which allows you to include or exclude the needle. So no need to use substr anymore.Assailant
C
5

Regexes would make it a lot more elegant:

// helo babe
echo preg_replace('~.*?x~', '', $str);

// Tuex helo babe
echo preg_replace('~.*?y~', '', $str);

But you can always try this:

// helo babe
echo str_replace(substr($str, 0, strpos($str, 'x')) . 'x', '', $str);

// Tuex helo babe
echo str_replace(substr($str, 0, strpos($str, 'y')) . 'y', '', $str);
Chaplin answered 27/10, 2010 at 20:37 Comment(0)
B
0
if(strpos($source_str, 'x') !== FALSE )
   $source_str = strstr($source_str, 'x');

Less elegant, but without x in the beginning:

if(strpos($source_str, 'x') !== FALSE )
   $source_str = substr(strstr($source_str, 'x'),1);
Bradawl answered 27/10, 2010 at 17:45 Comment(4)
this will include the 'x' within $source_str thoughTonus
Well thanks for your answer, but it's argueable that this is more elegant, and definitely slower "If you only want to determine if a particular needle occurs within haystack, use the faster and less memory intensive function strpos() instead." [source: it.php.net/strstr]Campbell
I'm confused. strpos is to check for substring occurence and it is used in my answer. strstr is to return portion of string, only if substring occurs. I find it more elegant because it does'nt need auxiliary variable, there is no misleading assignment in if() line and it's shorter. The only flaw of it is what @adam mentionedBradawl
sorry, I probably did not properly explain myself, I think using a strpos+strstr is slower than using a strpos+substr. I did not test for performance (so I'm not sure, but the speed difference might be unnoticable), but beside this, it's still a two line of codes with an if (very similar to code in my question), I was hoping someone could come out with a more concise solution.Campbell
R
0

I needed just this, and striving to keep it on one line for fun came up with this:

ltrim(strstr($source_str, $needle = "x") ?: $source_str, $needle);

The ternary operator was adapted in 5.3 to allow this to work.

Since PHP 5.3, it is possible to leave out the middle part of the ternary operator. Expression expr1 ?: expr3 returns expr1 if expr1 evaluates to TRUE, and expr3 otherwise.

NB. ltrim will trim multiple matching characters at the start of the string.

Rashida answered 7/1, 2015 at 16:28 Comment(0)
S
-1

Append a '-' at the end of $item so it always returns string before '-' even $item doesn't contain '-', because strpos by default returns the position of first occurrence of '-'.

substr($item,0,strpos($item.'-','-'))
Sabba answered 25/8, 2014 at 10:14 Comment(1)
I kinda liked this approach, why it is not good? I think it saves a compute cycle...Heterogeneous

© 2022 - 2024 — McMap. All rights reserved.