tags:

views:

819

answers:

10

PHP's explode function returns an array of strings split on some provided substring. It will return empty strings like this:

var_dump(explode('/', '1/2//3/'));
array(5) {
  [0]=>
  string(1) "1"
  [1]=>
  string(1) "2"
  [2]=>
  string(0) ""
  [3]=>
  string(1) "3"
  [4]=>
  string(0) ""
}

Is there some different function or option or anything that would return everything except the empty strings?

var_dump(different_explode('/', '1/2//3/'));
array(3) {
  [0]=>
  string(1) "1"
  [1]=>
  string(1) "2"
  [2]=>
  string(1) "3"
}
+2  A: 

function not_empty_string($s) { return $s !== ""; }

array_filter(explode('/', '1/2//3/'), 'not_empty_string');

James Aylett
Note: this is better than the 'bare' call to array_filter() if you might have "1/2//0/3" and want to keep the zero.
Bobby Jack
Good comment. I Wanted to suggested the 'bare' call, but yes, it will throw out the zero.
Jrgns
+5  A: 

Try preg_split.

$exploded = preg_split('@/@', '1/2//3/', NULL, PREG_SPLIT_NO_EMPTY);

ceejayoz
I think this is the most correct because it maintains the correct array indexes.
Ryono
@Ryono: what do you mean by that, exactly?
Bobby Jack
preg_split will return an array with sequential array indexes, (i.e. 0, 1, 2, 3). Some of the other suggestions using array_filter will return non-sequential array indexes because some elements are filtered out and you're left with array indexes like 0,1,3,7.
Ryono
+1  A: 

No.

If you do array_filter(explode('/', '1/2//3/')) you'll get all values that resolve to "false" filtered out (see http://uk.php.net/manual/en/function.array-filter.php).

Dave Gregory
Not sure what nitwit modded you down.
ceejayoz
Although I agree with the content of the answer,it doesn't exactly answer the question. At least give a reference to which answer your commenting (in the FAQ it says you can start an answer with @[username] and it will automatically link to the last answer from that user, but its not working for me)
Jrgns
This will remove '0', too, as it is false in a boolean context. So it might not be what you want!
ThiefMaster
For clarity, "No" was just an answer to "Is there some different function or option or anything" -- I could have been clearer by saying "No, there's nothing built in."
Dave Gregory
A: 

Write a wrapper function to strip them

function MyExplode($sep, $str)
{
    $arr = explode($sep, $str);
    foreach($arr as $item)
        if(item != "")
            $out[] = $item;
    return $out;
}
Fire Lancer
A: 

I usually wrap it in a call to array_filter, e.g.

var_dump(array_filter(explode('/', '1/2//3/'))
=>
array(3) {
  [0]=>
  string(1) "1"
  [1]=>
  string(1) "2"
  [3]=>
  string(1) "3"
}

Be aware, of course, that array keys are maintained; if you don't want this behaviour, remember to add an outer wrapper call to array_values().

Bobby Jack
Array filter filtesrs by FALSE by default. You need a callback function to make it work
Fire Lancer
Uh, Fire Lancer, read the docs. "Example #2 array_filter() without callback"
ceejayoz
Yeah, it depends what you call "work" - see my comment on James Aylett's post. Ironically, your version will also remove occurrences of "0" in the original string.
Bobby Jack
oh ok...I forgot php considered empty strings as FALSe, though it was just 0 and null
Fire Lancer
A: 

PHP's split function is similar to the explode function, except that it allows you to enter a regex pattern as the delimiter. Something to the effect of:

$exploded_arr = split('/\/+/', '1/2//3/');
Bullines
A: 

I haven't tested the other suggestions here, but this works:

function different_explode($mypattern,$mystring){
    $array1 = explode($mypattern,$mystring);
    $retArray = Array();
    foreach($array1 as $myval){
     if($myval != ''){
      array_push($retArray,$myval);
     }
    }
    return $retArray;
}
Derek Kurth
A: 

Use this function to filter the output of the explode function

  function filter_empty(&$arrayvar) {
        $newarray = array();
        foreach ($arrayvar as $k => $value)
            if ($value !== "")
                $newarray[$k] = $value;

        $arrayvar = $newarray;
    }
AntonioCS
If you're taking in the array as a reference, couldn't you then just unset() the empty-string indexes, without the need for an additional temporary array?
Bobby Jack
A: 

Just for variety:

array_diff(explode('/', '1/2//3/'), array(''))

This also works, but does mess up the array indexes unlike preg_split. Some people might like it better than having to declare a callback function to use array_filter.

Ryono
A: 

Regular expression solutions tend to be much slower than basic text replacement, so i'd replace double seperators with single seperators, trim the string of any whitespace and then use explode:

// assuming $source = '1/2//3/';
$source = str_replace('//', '/', $source);
$source = trim($source);
$parts = explode('/', $source);
adam