views:

76

answers:

3

I've got a string that could be in one of two forms:

prefix=key=value (which could have any characters, including '=')

or

key=value

So I need to split it either on the first or second equals sign, based on a boolean that gets set elsewhere. I'm doing this:

if ($split_on_second) {
    $parts = explode('=', $str, 3);
    $key = $parts[0] . '=' . $parts[1];
    $val = $parts[2];
} else {
    $parts = explode('=', $str, 2);
    $key = $parts[0];
    $val = $parts[1];
}

Which should work, but feels inelegant. Got any better ideas in php? (I imagine there's a regex-ninja way to do it, but I'm not a regex-ninja.;-)

+5  A: 

Edit:

Now I notice that you're getting the "if prefix should be there or not" from somewhere else, in which case my original solution is probably a bit less elegant. Instead, what I'd suggest is something like this:

$parts = explode('=', $str);
$key = array_shift($parts);
if($has_prefix) {
    $key .= '=' . array_shift($parts);
}
$val = implode('=', $parts);

.

My original response:

$parts = array_reverse(explode('=', $str));
$val = array_shift($parts);
$key = implode('=', array_reverse($parts));
Amber
@Amber Beat me to it! +1 for speed
drachenstern
Actually, I need to modify it slightly, since the $key part would be reversed atm. Edit: Fixed now.
Amber
seems like this would ignore the case where $value contains an = sign
Zak
Yeah Zak, I just saw that as well. So I edited my answer to add another version that works for the external flag bit. (Edit: Seems you had the same idea as I did on my edit. :))
Amber
looks correct now :) +1
Zak
Gave Zak the check, since he came up with two ideas, but +1 for you, too. Thanks! :)
sprugman
+2  A: 

how about just

$parts = explode('=', $str);
$key = array_shift( $parts);
//additionally, shift off the second part of the key
if($split_on_second)
{
    $key = $key . '=' . array_shift($parts);
}
//recombine any accidentally split parts of the value.
$val = implode($parts, "=");

Another variation

$explodeLimit = 2;
if($split_on_second)
{
    $explodeLimit++;
}
$parts = explode('=', $str, $explodeLimit);
//the val is what's left at the end
$val = array_pop($parts);
//recombine a split key if necessary
$key = implode($parts, "=");

And haven't tested this, but seems like it could be one of those fun optimizations that make code accurate but unreadable...

$explodeLimit = 2;
//when split_on_second is true, it bumps the value up to 3
$parts = explode('=', $str, $explodeLimit + $split_on_second );
//the val is what's left at the end
$val = array_pop($parts);
//recombine a split key if necessary
$key = implode($parts, "=");
Zak
+1 from me since we appear to have had the same idea :)
Amber
your optimization scares me. :) what if $split_on_second = 3? (In theory, it should be a strict bool, but with php, you never know. I suppose you could cast it to be sure.) I'd probably optimize it with `$explodeLimit = ($split_on_second) ? 3 : 2`, though.
sprugman
I know, that C style true/false stuff is crazy exploitable, right! It scares me to, but so do handgrenades, and the army still uses those!
Zak
+1  A: 
if ($prefix_exists) {
    list($prefix, $str) = explode('=', $str, 2);
    $prefix .= '=';
}

list($key, $val) = explode('=', $str, 2);
$key = $prefix . $key;
yjerem
This variation doesn't seem to recombine the prefix and (sub)key
Zak
aah thanks, fixed.
yjerem
+1 for accuracy :)
Zak