3

I'm trying to explode a string, but I need it to explode only at the last 'and' instead of every 'and'. Is there a way to do that?

<?php

$string = "one and two and three and four and five";
$string = explode(" and ", $string);

print_r($string);

?>

Result:

Array ( [0] => one [1] => two [2] => three [3] => four [4] => five )

Need Result:

Array ( [0] => one and two and three and four [1] => five )

frosty
  • 2,559
  • 8
  • 37
  • 73
  • @chris85 I thought maybe there was a pre-built function. I guess I'll just write my own function to do it. – frosty Mar 18 '16 at 21:08

6 Answers6

6

This seems easy enough to do using just basic string functions.

$x = strrpos($string, ' and ');
$s2 = array(substr($string, 0, $x), substr($string, $x + 5));
Don't Panic
  • 41,125
  • 10
  • 61
  • 80
1

I went a little more simplistic in my approach, using preg_match_all() with a simple regex instead:

$string = "one and two and three and four and five";
$pattern = '/(\w+\s)+/';
preg_match_all($pattern, $string, $matches);

$length = strlen($matches[0][0]);

echo $matches[0][0]; // 'one and two and three and four and'
echo substr($string, $length); // 'five'

The only issue here is the first match still has a trailing 'and' which could be gotten rid of, if need be, with a little simple coding. If your want more complex regex you could use positive look aheads and negative look behinds.

Jay Blanchard
  • 34,243
  • 16
  • 77
  • 119
  • Yeah. Check out my function. It doesn't have a trailing 'and'. – frosty Mar 18 '16 at 21:32
  • 1
    Cool - it's more verbose than what I am doing here @frosty – Jay Blanchard Mar 18 '16 at 21:32
  • Well, good thing is that it's a function, so this is first and last time I'll ever have to write it again. – frosty Mar 18 '16 at 21:38
  • True, I could create this as a function. That's the beautiful thing about code :) – Jay Blanchard Mar 18 '16 at 21:40
  • Personally, any time I have anything in my code that repeats at least once, I'll write a function for it. That cuts the code in at least half, and it makes coding a lot simpler. I got to say, that functions are probably my favorites in coding. – frosty Mar 18 '16 at 21:48
1

You can also use preg_split:

Single-character delimiter

$string = "one,two,three,four,five";
$delimiter = ",";

// The regexp will look like this:  /,([^,]+)$/   
$array = preg_split("/".$delimiter."([^".$delimiter."]+)$/", $string,
  -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);

print_r($array);

The regular expression matches the last delimiter with the last item, but captures only the item so that it's kept in the results thanks to PREG_SPLIT_DELIM_CAPTURE.

PREG_SPLIT_NO_EMPTY is there because, I'm not sure why, the split gives an empty string at the end.

Multi-character delimiter

The regular expression has to be adapted here, using a negative look-around (as explained in this answer):

$string = "one and two and three and four and five";
$delimiter = " and ";

$array = preg_split("/$delimiter((?(?!$delimiter).)*$)/", $string,
  -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);

print_r($array);

(?(?!$delimiter).)* means: match only characters that do no start the word $delimiter. The first ? prevents capturing an additional group.

Community
  • 1
  • 1
sylbru
  • 1,461
  • 1
  • 11
  • 19
0

I donot know if there is any other quick way for solving that need but you may try the code below;

$string = "one and two and three and four and five";
$stringArray = explode(" and ", $string);
$stringArrayItemCount = count($stringArray);
//Keep your last item
$stringArrayLastItem = $stringArray[$stringArrayItemCount-1];
//Remove last item from your array
unset($stringArray[$stringArrayItemCount-1]);
//Create new array imploding existing one + last item of your old array
$stringArray = array(implode(" and ",$stringArray),$stringArrayLastItem);

print_r($stringArray);

A working version of this example: http://ideone.com/qdZFtk

Hope this helps.

Cihan Uygun
  • 2,128
  • 1
  • 16
  • 26
0

Wrote a function to do this:

<?php

$string = "one and two and three and four and five";
$string = explodeLast(" and ", $string);

echo $string;

function explodeLast($explodeAt, $string) {

$explode = explode($explodeAt, $string);
$count = count($explode);
$counter = 0;
$string = null;

while ($counter < $count-1) {

if ($counter < $count-2) {
$string .= $explode[$counter].$explodeAt;
} //end of if ($counter < $count-2)
else {
$string .= $explode[$counter];
} //end of else not ($counter < $count-2)

$counter++;
} //end of while ($counter < $count)

return $string;

} //end of function explodeLast($explode, $explodeAt)

?>
frosty
  • 2,559
  • 8
  • 37
  • 73
0

This should work:

$str = 'one and two and three and four and five';
$breakWord = ' and ';

$output = str_split($str, strrpos($str, $breakWord) + strlen($breakWord));

var_dump($output);

http://sandbox.onlinephpfunctions.com/code/0149b3ff973485befe97a1c6b241a6764bd2f289

EDIT - regexp use:

<?php
$str = 'one and two and three and four and the last part is actually longer than the first part';
$pattern = "/(.+) and (?!.* and )(.+)/";
preg_match($pattern, $str, $matches);

var_dump($matches);

http://sandbox.onlinephpfunctions.com/code/0bc68f46fe594e360134bdca256e5916a2f42f74

barat
  • 1,040
  • 8
  • 14
  • I thought about this too, but it runs into problems when `$str = 'one and two and three and four and the last part is actually longer than the first part';` – Don't Panic Mar 18 '16 at 22:00
  • How about this? – barat Mar 18 '16 at 22:19
  • Yeah - I saw it too in this thread after posting this ... but this is "new" :) http://sandbox.onlinephpfunctions.com/code/0bc68f46fe594e360134bdca256e5916a2f42f74 – barat Mar 18 '16 at 22:55