3

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?

mickmackusa
  • 43,625
  • 12
  • 83
  • 136

10 Answers10

11

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

Daniel A. White
  • 187,200
  • 47
  • 362
  • 445
  • Oh yeah good idea - a for loop that increments by two and concatenates - thanks. –  May 08 '09 at 16:59
  • This answer looks like a comment by modern Stack Overflow standards. A more generous answer would actually show the coded implementation. – mickmackusa Oct 22 '22 at 02:14
8
$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
  • 93,428
  • 18
  • 118
  • 189
  • 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. – cgp May 08 '09 at 17:11
  • Remove the surrounding parenthesis and you’ll get just one array. – Gumbo May 09 '09 at 16:43
  • 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 May 09 '09 at 16:47
3

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
  • 9,833
  • 3
  • 32
  • 41
  • 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 May 12 '09 at 13:34
2

$string = "This is my test case for an example.";

preg_match_all("/[a-zA-Z0-9]+\ [a-zA-Z0-9]+/", $string, $matches);
print_r($matches);

Andrew Sledge
  • 10,163
  • 2
  • 29
  • 30
1
$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
  • 122,029
  • 33
  • 303
  • 309
1

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
  • 17,274
  • 5
  • 40
  • 40
  • Since you want notification, I got a different solution for this problem you might be interested in. – OIS May 11 '09 at 21:57
1

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
  • 18,754
  • 7
  • 41
  • 61
  • 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 May 12 '09 at 20:32
  • 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 May 12 '09 at 20:52
0

I wouldn't use any of the previously posted answers in my own project.

The cleanest, most direct tool is preg_split(). Match the first sequence of non-space characters, then a space, then the next sequence of non-space characters, then "forget" the matched characters and match the space which must be consumed during the exploding process.

\K means "restart the fullstring match from here". Using \K eliminates the need to implement a capture group as well as a PREG_ flag.

Code: (Demo)

$string = "This is my test case for an example.";

var_export(
    preg_split('~[^ ]+ [^ ]+\K ~', $string)
    // or      '~\S+ \S+\K ~'
);

Output:

array (
  0 => 'This is',
  1 => 'my test',
  2 => 'case for',
  3 => 'an example.',
)
mickmackusa
  • 43,625
  • 12
  • 83
  • 136
0
    $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
  • 339,989
  • 67
  • 413
  • 406
0

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!