php explode: dividir a string em palavras usando o espaço um delimitador

$str = "This is a string"; $words = explode(" ", $str); 

Funciona bem, mas os espaços ainda estão disponíveis:

 $words === array ('This', 'is', 'a', '', '', '', 'string');//true 

Preferia ter palavras apenas sem espaços e manter as informações sobre o número de espaços separados.

 $words === array ('This', 'is', 'a', 'string');//true $spaces === array(1,1,4);//true 

Apenas adicionado: (1, 1, 4) significa um espaço após a primeira palavra, um espaço após a segunda palavra e 4 espaços após a terceira palavra.

Existe alguma maneira de fazê-lo rápido?

Obrigado.

Para dividir a Cadeia em uma matriz, você deve usar preg_split :

 $string = 'This is a string'; $data = preg_split('/\s+/', $string); 

A sua segunda parte (espaços de contagem):

 $string = 'This is a string'; preg_match_all('/\s+/', $string, $matches); $result = array_map('strlen', $matches[0]);// [1, 1, 4] 

$financialYear = 2015-2016;

 $test = explode('-',$financialYear); echo $test[0]; // 2015 echo $test[1]; // 2016 

Aqui está uma maneira, dividindo a string e executando um regex uma vez, então analisando os resultados para ver quais segmentos foram capturados como a divisão (e, portanto, apenas espaços em branco) ou quais são palavras:

 $temp = preg_split('/(\s+)/', $str, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY); $spaces = array(); $words = array_reduce( $temp, function( &$result, $item) use ( &$spaces) { if( strlen( trim( $item)) === 0) { $spaces[] = strlen( $item); } else { $result[] = $item; } return $result; }, array()); 

Você pode ver a partir desta demo que $words é:

 Array ( [0] => This [1] => is [2] => a [3] => string ) 

E $spaces é:

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

Outra maneira de fazê-lo seria usar o loop foreach.

 $str = "This is a string"; $words = explode(" ", $str); $spaces=array(); $others=array(); foreach($words as $word) { if($word==' ') { array_push($spaces,$word); } else { array_push($others,$word); } } 

Você pode usar preg_split() para a primeira matriz:

 $str = 'This is a string'; $words = preg_split('#\s+#', $str); 

E preg_match_all() para a matriz $spaces :

 preg_match_all('#\s+#', $str, $m); $spaces = array_map('strlen', $m[0]); 

Aqui estão os resultados dos testes de desempenho:

 $str = "This is a string"; var_dump(time()); for ($i=1;$i<100000;$i++){ //Alma Do Mundo - the winner $rgData = preg_split('/\s+/', $str); preg_match_all('/\s+/', $str, $rgMatches); $rgResult = array_map('strlen', $rgMatches[0]);// [1,1,4] } print_r($rgData); print_r( $rgResult); var_dump(time()); for ($i=1;$i<100000;$i++){ //nickb $temp = preg_split('/(\s+)/', $str, -1,PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY); $spaces = array(); $words = array_reduce( $temp, function( &$result, $item) use ( &$spaces) { if( strlen( trim( $item)) === 0) { $spaces[] = strlen( $item); } else { $result[] = $item; } return $result; }, array()); } print_r( $words); print_r( $spaces); var_dump(time()); 

int (1378392870) Array ([0] => Este [1] => é [2] => a [3] => string) Array ([0] => 1 [1] => 1 [2] => 4) int (1378392871) Array ([0] => Este [1] => é [2] => a [3] => string) Array ([0] => 1 [1] => 1 [2] => 4) int (1378392873)