2008-09-15 23 views
28

La función de explosión de PHP devuelve una matriz de cadenas divididas en alguna subcadena proporcionada. Se volverá cadenas vacías como esto:¿Explotar que no devuelve cadenas vacías?

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

¿Hay alguna función o la opción o algo diferente que devolver todo excepto las cadenas vacías?

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

Respuesta

53

Trate preg_split.

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

+1

Creo que este es el más correcto porque mantiene los índices de matriz correctos. –

+0

@Ryono: ¿qué quieres decir con eso, exactamente? –

+5

preg_split devolverá una matriz con índices de matriz secuencial, (es decir, 0, 1, 2, 3). Algunas de las otras sugerencias que usan array_filter devolverán índices de matriz no secuenciales porque algunos elementos se filtran y le quedan índices de matriz como 0,1,3,7. –

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

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

Nota: esto es mejor que el 'desnudo' llamar a array_filter() si es posible que tenga "1/2 // 0/3" y quiere a mantener el cero. –

+0

Buen comentario. Quería sugerir la llamada 'desnuda', pero sí, arrojará el cero. – Jrgns

17

array_filter eliminará los campos en blanco, aquí es un ejemplo sin el filtro:

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

impresiones:

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

Con el filtro:

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

Lienzo:

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

Usted obtendrá todos los valores que están asociados a "falso" filtrados.

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

+5

Esto eliminará '0' también, ya que es falso en un contexto booleano. ¡Entonces podría no ser lo que quieres! – ThiefMaster

+0

Para mayor claridad, "No" fue solo una respuesta a "¿Hay alguna función u opción diferente o algo así?" - Pude haber sido más claro al decir "No, no hay nada integrado". –

+0

Esto era justo lo que necesitaba. Tenía que asegurarme de que una matriz constante siempre tuviera cuatro valores de cadena, que deben obtenerse de una explosión. Sin embargo, si falla el estallido, necesitaba proporcionar un valor de reserva en [0]. Lo he logrado de esta manera: 'array_filter (explode (',', ($ string, 4))) + ['default_value', '', '', '']'. De esta forma, una explosión fallida no contendrá ningún valor, y el resultado será la segunda matriz. Sin duda es poco ortodoxo, pero es una solución limpia para una constante como esta. –

0

escribir una función de envoltura para despojarlos

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

por lo general lo envuelve en una llamada a array_filter, por ejemplo,

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

Tenga en cuenta, por supuesto, que las teclas de matriz se mantienen; si no desea desea este comportamiento, recuerde agregar una llamada contenedora externa a array_values ​​().

+0

Filtradores de filtro de matriz por FALSE de forma predeterminada. Necesita una función de devolución de llamada para que funcione –

+0

Uh, Fire Lancer, lea los documentos. "Example # 2 array_filter() sin devolución de llamada" – ceejayoz

+0

Sí, depende de lo que usted llame "trabajo" - vea mi comentario en la publicación de James Aylett. Irónicamente, su versión también eliminará las ocurrencias de "0" en la cadena original. –

-1

El PHP split function es similar a la función de explosión, excepto que le permite ingresar un patrón de expresiones regulares como el delimitador. Algo en el sentido de:

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

Esta función se ha DETERMINADO a partir de PHP 5.3.0. Confiar en esta característica es altamente desaconsejado. – PowerKiKi

0

no he probado las otras sugerencias aquí, pero esto funciona:

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

Utilice esta función para filtrar la salida de la función de explotar

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

     $arrayvar = $newarray; 
    } 
+0

Si está tomando la matriz como referencia, ¿no podría entonces simplemente desarmar() los índices de cadenas vacías, sin la necesidad de una matriz temporal adicional? –

6

sólo por la variedad:

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

Esto también funciona, pero estropea los índices de matriz a diferencia de preg_split. A algunas personas les puede gustar más que tener que declarar una función de devolución de llamada para usar array_filter.

+0

No hay necesidad de una función de devolución de llamada cuando utiliza array_filter si está filtrando solo valores falsy como cadena vacía – alucic

0

soluciones de expresiones regulares tienden a ser mucho más lento que la sustitución de texto básico, por lo que me reemplazan dobles separadores con separadores individuales, recortar la cadena de cualquier espacio en blanco y luego usar explotar:

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

He utilizado este en TYPO3, mira el $onlyNonEmptyValues parámetro:

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; 
} 

no desordenar los índices:

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

Resultado:

array(3) { 
    [0]=> 
    string(1) "1" 
    [1]=> 
    string(1) "2" 
    [2]=> 
    string(1) "3" 
} 
1

Aquí es una solución que debe ser la salida de un arreglo recientemente indexada.

$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; 
} 

Aunque es bastante similar a otra sugerencia, esta implementación tiene el beneficio del uso genérico. Para matrices con elementos que no sean de cadena, proporcione un valor vacío tipado como segundo argumento.

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'));

.

.

.

Con un argumento filtro opcional ..

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; 
} 

Con el uso ..

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

Volviendo array_deflate en una forma de elementos de elección de procesamiento y sacarlos de su matriz. También es más agradable convertir la instrucción if en una función de comparación que también se pasa como argumento en caso de que te apetezca.

array_inflate siendo al revés, tomaría una matriz adicional ya que el primer parámetro que coincide se inserta mientras que las no coincidencias se filtran.

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; 
} 

Con el uso ..

$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; 
} 

lo tanto proporcionar un algoritmo ideal para los problemas educativos del mundo. Y me detendré allí antes de modificar esto en otra cosa ...

0

Sin sobrecarga de expresiones regulares - debe ser razonablemente eficiente, strlen simplemente cuenta los bytes

Drop the array_values ​​() si no se preocupan por los índices

lo hacen en función de explode_interesting ($ matriz, $ fix_index = 0) si desea

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

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

disfrutar, Jeff

Cuestiones relacionadas