Взрываться, что не возвращает пустые строки? - PullRequest
30 голосов
/ 15 сентября 2008

PHP функция разнесения возвращает массив строк, разделенных на некоторую предоставленную подстроку. Он вернет пустые строки, например:

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) ""
}

Есть ли какая-то другая функция или опция или что-нибудь, что могло бы вернуть все , кроме пустых строк?

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

Ответы [ 13 ]

58 голосов
/ 15 сентября 2008

Попробуйте preg_split .

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

20 голосов
/ 15 сентября 2008

array_filter удалит пустые поля, вот пример без фильтра:

print_r(explode('/', '1/2//3/'))

печать:

Array
(
    [0] => 1
    [1] => 2
    [2] =>
    [3] => 3
    [4] =>
)

С фильтром:

php> print_r(array_filter(explode('/', '1/2//3/')))

Печать:

Array
(
    [0] => 1
    [1] => 2
    [3] => 3
)

Вы получите все значения, которые разрешены как "ложные", отфильтрованные.

см. http://uk.php.net/manual/en/function.array-filter.php

6 голосов
/ 15 сентября 2008

Только для разнообразия:

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

Это также работает, но портит индексы массива в отличие от preg_split. Некоторым людям это может понравиться лучше, чем объявлять функцию обратного вызова для использования array_filter.

4 голосов
/ 15 сентября 2008
function not_empty_string($s) {
  return $s !== "";
}

array_filter(explode('/', '1/2//3/'), 'not_empty_string');
1 голос
/ 11 марта 2016

Вот решение, которое должно выводить вновь проиндексированный массив.

$result = array_deflate( explode( $delim, $array) );

function array_deflate( $arr, $emptyval='' ){
    $ret=[];
    for($i=0,$L=count($arr); $i<$L; ++$i)
        if($arr[$i] !== $emptyval) $ret[]=$arr[$i];
    return $ret;
}

Хотя эта реализация довольно похожа на некоторые другие предложения, она имеет преимущество общего использования. Для массивов с нестроковыми элементами укажите типизированное пустое значение в качестве второго аргумента.

array_deflate( $objArray, new stdClass() );

array_deflate( $databaseArray, NULL );

array_deflate( $intArray, NULL );

array_deflate( $arrayArray, [] );

array_deflate( $assocArrayArray, [''=>NULL] );

array_deflate( $processedArray, new Exception('processing error') );

.

.

.

С необязательным аргументом фильтра ..

function array_deflate( $arr, $trigger='', $filter=NULL, $compare=NULL){
    $ret=[];
    if ($filter === NULL) $filter = function($el) { return $el; };
    if ($compare === NULL) $compare = function($a,$b) { return $a===$b; };

    for($i=0,$L=count($arr); $i<$L; ++$i)
        if( !$compare(arr[$i],$trigger) ) $ret[]=$arr[$i];
        else $filter($arr[$i]);
    return $ret;
}

С использованием ..

function targetHandler($t){ /* .... */ }    
array_deflate( $haystack, $needle, targetHandler );

Превращение array_deflate в способ обработки элементов выбора и удаления их из вашего массива. Также лучше превратить оператор if в функцию сравнения, которая также передается в качестве аргумента, если вам это нравится.

array_inflate в противном случае в качестве первого параметра будет выбран дополнительный массив, для которого сопоставляются совпадения, а несоответствия фильтруются.

function array_inflate($dest,$src,$trigger='', $filter=NULL, $compare=NULL){
    if ($filter === NULL) $filter = function($el) { return $el; };
    if ($compare === NULL) $compare = function($a,$b) { return $a===$b; };

    for($i=0,$L=count($src); $i<$L; ++$i)
        if( $compare(src[$i],$trigger) ) $dest[]=$src[$i];
        else $filter($src[$i]);
    return $dest;
}

С использованием ..

$smartppl=[];    
$smartppl=array_inflate( $smartppl,
                         $allppl,
                         (object)['intelligence'=>110],
                         cureStupid,
                         isSmart);

function isSmart($a,$threshold){
    if( isset($a->intellgence) )    //has intelligence?
        if( isset($threshold->intellgence) )    //has intelligence?
            if( $a->intelligence >= $threshold->intelligence )
                return true;
            else return INVALID_THRESHOLD; //error
        else return INVALID_TARGET; //error
    return false;
}

function cureStupid($person){
    $dangerous_chemical = selectNeurosteroid();
    applyNeurosteroid($person, $dangerous_chemical);

    if( isSmart($person,(object)['intelligence'=>110]) ) 
        return $person;
    else 
        lobotomize($person);

    return $person;
}

Таким образом, обеспечивая идеальный алгоритм для мировых проблем образования. Ааа, я остановлюсь там, прежде чем подправлю это во что-то другое ..

1 голос
/ 02 мая 2014

Я использовал это в TYPO3 , посмотрите на параметр $onlyNonEmptyValues:

function trimExplode($delim, $string, $onlyNonEmptyValues=0){
    $temp = explode($delim,$string);
    $newtemp=array();
    while(list($key,$val)=each($temp))      {
        if (!$onlyNonEmptyValues || strcmp("",trim($val)))      {
            $newtemp[]=trim($val);
        }
    }
    reset($newtemp);
    return $newtemp;
}

Не портит индексы:

var_dump(trimExplode('/', '1/2//3/',1));

Результат:

array(3) {
  [0]=>
  string(1) "1"
  [1]=>
  string(1) "2"
  [2]=>
  string(1) "3"
}
0 голосов
/ 24 марта 2016

Нет необходимости в регулярных выражениях - должно быть достаточно эффективным, strlen просто считает байты

Удалите array_values ​​(), если вам не нужны индексы

Превратите это в функцию explode_interesting ($ array, $ fix_index = 0), если хотите

<code>$interesting = array_values( 
                 array_filter(
                   explode('/', '/1//2//3///4/0/false' ),
                   function ($val) { return strlen($val); }
               ));

echo "<pre>", var_export( $interesting, true ), "
";

наслаждайся, Джефф

0 голосов
/ 16 сентября 2008

Решения с регулярными выражениями, как правило, работают намного медленнее, чем обычная замена текста, поэтому я бы заменил двойной разделитель на один разделитель, обрезал строку любого пробела и затем использовал бы разрыв:

// assuming $source = '1/2//3/';
$source = str_replace('//', '/', $source);
$source = trim($source);
$parts = explode('/', $source);
0 голосов
/ 15 сентября 2008

Используйте эту функцию для фильтрации выходных данных функции разнесения

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

        $arrayvar = $newarray;
    }
0 голосов
/ 15 сентября 2008

Я не проверял другие предложения здесь, но это работает:

function different_explode($mypattern,$mystring){
    $array1 = explode($mypattern,$mystring);
    $retArray = Array();
    foreach($array1 as $myval){
        if($myval != ''){
            array_push($retArray,$myval);
        }
    }
    return $retArray;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...