views:

769

answers:

9

Lets say I have a string - $string = "This is my test case for an example."

If I do explode based on ' ' I get an Array('This','is','my','test','case','for','an','example.');

What I want is an explode for every other space: Array('This is','my test','case for','an example.').

The string may have an odd # of words, so the last item in the array may not contain two words.

Anyone know how to do this?

+10  A: 

I would look through the results, and concatenate the strings after the fact.

Daniel A. White
Oh yeah good idea - a for loop that increments by two and concatenates - thanks.
Seems like the easiest way to go about doing it.
Andrew Szeto
+1  A: 
$matches = array();
preg_match_all('/\S+(?:\s[A-Za-z0-9.]+|$)/',
    'This is my test case for an example.',
    $matches
);
print_r($matches);
preg_match_all('/\S+(?:\s[A-Za-z0-9.]+|$)/',
    'This is my test case for example.',
    $matches
);
print_r($matches);
chaos
+6  A: 
$matches = array();
preg_match_all('/([A-Za-z0-9\.]+(?: [A-Za-z0-9\.]+)?)/',
       'This is my test case for an example.',$matches);

print_r($matches);

yields:

Array
(
  [0] => Array
    (
        [0] => This is
        [1] => my test
        [2] => case for
        [3] => an example.
    )

  [1] => Array
    (
        [0] => This is
        [1] => my test
        [2] => case for
        [3] => an example.
    )

)

update fixed it to match a single word at the end of the sentence

Evert
Nice, add in if possible the check at the end to see if the last element has a single element as requested by the question.
altCognito
done, thank you
Evert
Remove the surrounding parenthesis and you’ll get just one array.
Gumbo
Good work figuring it out, but I'm putting my +1 for Daniel's answer, sorry. Though this is correct and works, the other method would be more understandable and maintainable, IMO.
nickf
+1  A: 
Andrew Sledge
This will choke if non-alphanumeric characters are present in any of the words.
karim79
So modify it: this is just an example.
Andrew Sledge
A: 
    $str = "This is my test case for an example.";
    $arr = split(' ', $str);
    $newArr = array();
    $count = count($arr);
    for($i=0;$i<$count;$i = $i + 2) {
        $newArr[] = $arr[$i] . ' ' . $arr[$i+1];
    }


array(4) {
  [0]=>
  string(7) "This is"
  [1]=>
  string(7) "my test"
  [2]=>
  string(8) "case for"
  [3]=>
  string(11) "an example."
}
karim79
+1  A: 

Something You Can Re-Use for Other Scenarios: (always better IMO).

While probably not the most elegant solution, this does follow the general concept syntax of other PHP core functions...

In any case... This uses recursion. It is flexible in that it allows you to specify the size of the chunk (in case you'd like to do that down the road or for a different project). I did this as more of a personal challenge to see what I could come up with.

<?php
function chunk_explode($glue=' ',$pieces='',$size=2,$final=array()) {
    if(!is_string($pieces) && !is_array($pieces)) 
        return false;

    if(is_string($pieces))
        $pieces = explode($glue,$pieces);

    $num_pieces = sizeof($pieces);
    if($num_pieces <= 0) 
       return $final;

    if($num_pieces >= $size) {
        $arr_chunk = array_chunk($pieces, $size);
        array_push($final,implode($glue,$chunk[0]));
        for($i=0;$i<=$size;$i++) { array_shift($pieces); }
        return chunk_explode($glue,$pieces,$size,$final);
    }
    array_push($final,implode($glue,$pieces));
    return $final;
}
$string = "This is my test case for an example.";
chunk_explode(' ',$string,3);

If this chunk_explode function sucks, let me know so I can learn from my mistakes.

KyleFarris
Since you want notification, I got a different solution for this problem you might be interested in.
OIS
A: 

Well obviously this isn't the best solution, but it was fun figuring it out in my own way. Still so much to learn...

function solveThisPuzzle($string) {

$modified_string = preg_replace('(\s)', '+', $string, -1, $count); 
$words = explode('+', $modified_string);

$phrases_arr = array();

for($i = 1; $i < $count+1; $i++) {
 if(($i % 2)) {
  $phrase = $words[$i-1].' '.$words[$i];
  $phrases_arr[] = $phrase;
  unset($phrases_arr[$i]);
 } elseif($i == $count) {
   $phrase = $words[$i];
   $phrases_arr[] = $phrase;
  } else {   
   $phrase = NULL;
  }
}

foreach($phrases_arr as $final_phrase) {
 $solution .= $final_phrase.'<br />';
}

 return $solution;

}

$string = "This is my test case for an example, huzzah!";
echo solveThisPuzzle($string);

This is
my test
case for
an example,
huzzah!
+1  A: 

A function which can be used for different delimiters and numbers.

function explodeEveryNth($delimiter, $string, $n) {
    $arr = explode($delimiter, $string);
    $arr2 = array_chunk($arr, $n);
    $out = array();
    for ($i = 0, $t = count($arr2); $i < $t; $i++) {
     $out[] = implode($delimiter, $arr2[$i]);
    }
    return $out;
}

Test code

var_dump(explodeEveryNth(' ', 'This is a test string', 2));
OIS
Yeah, that's definitely cleaner than mine. I like it! I was actually just exploring recursive function so I wanted to see if I could do it that way. I tested yours and it's way faster... For 1502 number of words:Chunk Explode = 0.49018907546997 seconds vs. Explode Every N = 0.0034539699554443 seconds.
KyleFarris
A: 

There are 75 array functions in PHP, let's try to use them instead of for loops!!

I like Kyle's function name. (I'll assume you aren't running 5.3 and suffer with create_function.)

 function chunk_explode($string, $chunks = 2, $delim = ' ') {
     $A = explode($delim, $string);
     $A = array_chunk($A, $chunks);
     return array_map(
         create_function('$x',
            'return implode(\'' . $delim . '\',$x);'), $A);
 }
jmucchiello
array_map is slower then for loops. Its only usefull for iterating multiple arrays. create_function is also VERY slow, at least make a helper function or wait for PHP5.3.
OIS
Array_map is more readable than for loops. My answer notes that PHP 5.3 avoid the create_function suffering, why did you reiterate what I said? Similarly, how do I pass $delim to a separate function called from array_map?
jmucchiello