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

Works fine, but spaces still go into array:

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

I would prefer to have words only with no spaces and keep the information about the number of spaces separate.

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

Just added: (1, 1, 4) means one space after the first word, one space after the second word and 4 spaces after the third word.

Is there any way to do it fast?

Thank you.

Alan Moore
  • 68,531
  • 11
  • 88
  • 149
Haradzieniec
  • 8,150
  • 26
  • 100
  • 199

6 Answers6

31

For splitting the String into an array, you should use preg_split:

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

Your second part (counting spaces):

$string = 'This is a    string';
preg_match_all('/\s+/', $string, $matches);
$result = array_map('strlen', $matches[0]);// [1, 1, 4]
Alma Do
  • 35,363
  • 9
  • 65
  • 99
2

Here is one way, splitting the string and running a regex once, then parsing the results to see which segments were captured as the split (and therefore only whitespace), or which ones are words:

$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());

You can see from this demo that $words is:

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

And $spaces is:

Array
(
    [0] => 1
    [1] => 1
    [2] => 4
)
nickb
  • 56,839
  • 11
  • 91
  • 130
  • thank you very much for you answer. I've tested both your and Alma Do Mundo / silkfire solutions. All solutions work fine, but Alma Do Mundo's work about two times faster. Thank you for your solution anyway. You can compare both if you want (pleae see my reply on my own question in a second). – Haradzieniec Sep 05 '13 at 15:06
1

You can use preg_split() for the first array:

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

And preg_match_all() for the $spaces array:

preg_match_all('#\s+#', $str, $m);
$spaces = array_map('strlen', $m[0]);
silkfire
  • 20,433
  • 12
  • 70
  • 93
1

Another way to do it would be using foreach loop.

$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);
}
}
Ahmar Ali
  • 930
  • 5
  • 24
  • 47
  • Thank you. However, it collects spaces, but it doesn't' contain information about number of spaces between the words. – Haradzieniec Sep 05 '13 at 15:02
0

Here are the results of performance tests:

$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] => This [1] => is [2] => a [3] => string ) Array ( [0] => 1 [1] => 1 [2] => 4 ) int(1378392871) Array ( [0] => This [1] => is [2] => a [3] => string ) Array ( [0] => 1 [1] => 1 [2] => 4 ) int(1378392873)

Haradzieniec
  • 8,150
  • 26
  • 100
  • 199
0

$financialYear = 2015-2016;

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