tags:

views:

369

answers:

8

How can I explode every third semicolon (;) as a piece?

example data: $string = piece1;piece2;piece3;piece4;piece5;piece6;piece7;piece8;

example output would be:

$output[0] = piece1;piece2:piece3;

$output[1] = piece4;piece5;piece6;

$output[2] = piece7;piece8;

Thanks!

+4  A: 

I am sure you can do something slick with regular expressions, but why not just explode the each semicolor and then add them three at a time.

$tmp = explode(";", $string);
$i=0;
$j=0;

foreach($tmp as $piece) {
   if(! ($i++ %3)) $j++;   //increment every 3 
   $result[$j] .= $piece;
}
jW
I was thinking the exact same thing...although there must be a prettier way with regular expressions.
Darryl Hein
there very well could be. But, since I am terrible with regular expressions, I avoid them and do tricky stuff like above
jW
"although there must be a prettier way with regular expressions." hahahahahahahaha
nickf
bingo. exactly what i need
stunnaman
+1  A: 

Maybe approach it from a different angle. Explode() it all, then combine it back in triples. Like so...

$str = "1;2;3;4;5;6;7;8;9";
$boobies = explode(";", $array);
while (!empty($boobies))
{
  $foo = array();
  $foo[] = array_shift($boobies);
  $foo[] = array_shift($boobies);
  $foo[] = array_shift($boobies);
  $bar[] = implode(";", $foo) . ";";
}

print_r($bar);

Array ( [0] => 1;2;3; [1] => 4;5;6; [2] => 7;8;9; )

Derek Gathright
Charming variable naming.
linead
Downvote removed, but I have to say I find while (!empty($boobies)) rather disturbing. And I hope you don't pornify your variable names at work.
karim79
+1  A: 
$string = "piece1;piece2;piece3;piece4;piece5;piece6;piece7;piece8;piece9;";
preg_match_all('/([A-Za-z0-9\.]*;[A-Za-z0-9\.]*;[A-Za-z0-9\.]*;)/',$string,$matches);

print_r($matches);

Array
(
    [0] => Array
        (
            [0] => piece1;piece2;piece3;
            [1] => piece4;piece5;piece6;
            [2] => piece7;piece8;piece9;
        )

    [1] => Array
        (
            [0] => piece1;piece2;piece3;
            [1] => piece4;piece5;piece6;
            [2] => piece7;piece8;piece9;
        )

)
Derek Gathright
This fails when the number of pieces isn't a multiple of 3.
mercator
A: 

Here's a regex approach, which I can't say is all too good looking.

$str='';
for ($i=1; $i<20; $i++) {
    $str .= "$i;";
}

$split = preg_split('/((?:[^;]*;){3})/', $str, -1,
                    PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);

Output:

Array
(
    [0] => 1;2;3;
    [1] => 4;5;6;
    [2] => 7;8;9;
    [3] => 10;11;12;
    [4] => 13;14;15;
    [5] => 16;17;18;
    [6] => 19;
)
Sebastian P.
+1  A: 

Another regex approach.

<?php
$string = 'piece1;piece2;piece3;piece4;piece5;piece6;piece7;piece8';
preg_match_all('/([^;]+;?){1,3}/', $string, $m, PREG_SET_ORDER);
print_r($m);

Results:

Array
(
    [0] => Array
        (
            [0] => piece1;piece2;piece3;
            [1] => piece3;
        )

    [1] => Array
        (
            [0] => piece4;piece5;piece6;
            [1] => piece6;
        )

    [2] => Array
        (
            [0] => piece7;piece8
            [1] => piece8
        )

)
Glass Robot
to format the output array as described: $m = array_map(create_function('$a', 'return $a[0];'), $m);
danamlund
A: 

Regex Split

$test = ";2;3;4;5;6;7;8;9;10;;12;;14;15;16;17;18;19;20";
// match all groups that:
// (?<=^|;) follow the beginning of the string or a ;
// [^;]*  have zero or more non ; characters
// ;? maybe a semi-colon (so we catch a single group)
// [^;]*;? again (catch second item)
// [^;]* without the trailing ; (to not capture the final ;)
preg_match_all("/(?<=^|;)[^;]*;?[^;]*;?[^;]*/", $test, $matches);
var_dump($matches[0]);


array(7) {
  [0]=>
  string(4) ";2;3"
  [1]=>
  string(5) "4;5;6"
  [2]=>
  string(5) "7;8;9"
  [3]=>
  string(6) "10;;12"
  [4]=>
  string(6) ";14;15"
  [5]=>
  string(8) "16;17;18"
  [6]=>
  string(5) "19;20"
}
gnarf
+2  A: 

Essentially the same solution as the other ones that explode and join again...

$tmp = explode(";", $string);

while ($tmp) {
    $output[] = implode(';', array_splice($tmp, 0, 3));
};
mercator
+2  A: 

Easiest solution I can think of is:

$chunks = array_chunk(explode(';', $input), 3);
$output = array_map(create_function('$a', 'return implode(";",$a);'), $chunks);
cletus
+1 for the first line, -1 for the second ;) (using `create_function()` is bad practive). Starting from PHP 5.3 you can use a lambda function for it, though: `$output = array_map(function($a) { return implode(';', $a); }, $chunks);`
mercator
Yeah true. I guess we can start using 5.3 features in answers now it's released.
cletus