0

I know "explode" splits the string and turns it into an array for every occurrence. But how do I split on the third occurrence and keep everything after the third occurrence?

Examples 1:

$split = explode(':', 'abc-def-ghi::State.32.1.14.16.5:A);

I would like this to output:

echo $split[0];  // abc-def-ghi::State.32.1.14.16.5
echo $split[1];  // A

Examples 2:

$split = explode(':', 'def-ghi::yellow:abc::def:B);

I would like this to output:

echo $split[0];  // def-ghi::yellow
echo $split[1];  // abc::def:B
andrewarnier
  • 159
  • 2
  • 8
  • 20
  • use preg_split. explode() is a simple string operation, preg_split uses regexes and makes it far easier to specify complicated split points. – Marc B Aug 22 '16 at 15:34

4 Answers4

3

Split a string using a delimiter and return two strings split on the the nth occurrence of the delimiter.

  • 1) Explode using the delimiter.
  • 2) If the required array entry is set then find the position of that sting in the original source.
  • 3) Split into two string at the postion of that string.

Demonstration at eval.in

Code:

<?php
/**
 * Split a string using a delimiter and return two strings split on the the nth occurrence of the delimiter.

 *  @param string  $source
 *  @param integer $index - one-based index
 *  @param char    $delimiter
 *
 * @return array  - two strings 
 */
function strSplit($source, $index, $delim)
{
  $outStr[0] = $source;
  $outStr[1] = '';

  $partials = explode($delim, $source);

  if (isset($partials[$index]) && strlen($partials[$index]) > 0) {
     $splitPos = strpos($source, $partials[$index]);

     $outStr[0] = substr($source, 0, $splitPos - 1);
     $outStr[1] = substr($source, $splitPos);
  }

  return $outStr;
}

Test:

$split = strSplit('abc-def-ghi::State.32.1.14.16.5:A', 3, ':');

var_dump($split);

$split1 = strSplit('def-ghi::yellow:', 3, ':');

var_dump($split, $split1);

Output:

array(2) {
  [0]=>
  string(31) "abc-def-ghi::State.32.1.14.16.5"
  [1]=>
  string(1) "A"
}
array(2) {
  [0]=>
  string(31) "abc-def-ghi::State.32.1.14.16.5"
  [1]=>
  string(1) "A"
}
array(2) {
  [0]=>
  string(16) "def-ghi::yellow:"
  [1]=>
  string(0) ""
}
Ryan Vincent
  • 4,483
  • 7
  • 22
  • 31
1

Sadly, no one has offered preg_split() yet -- so I will.

You merely need to match alternating sequences of non-colons followed by a colon three times. I have written \K before the : so that only the third occuring colon is consumed during the explosion. To ensure that no characters are consumed, just move the \K to the end of the pattern (just before the closing /). * in my pattern means "zero or more continuous characters obeying the preceding rule". [^:] means any non-colon character.

To limit the size of the output array to a maximum of 2 elements, use 2 as the third function parameter. Without the limiting parameter, then it is possible that the 6th, 9th, etc colons will be consumed while creating more elements in the output. If you encounter an unwanted empty element in the output because of the structure of your input string, you can use PREG_SPLIT_NO_EMPTY as the fourth function parameter to omit it.

Code: (Demo)

preg_split(
    '/(?:[^:]*\K:){3}/',
    $string,
    2
)

abc-def-ghi::State.32.1.14.16.5:A becomes:

array (
  0 => 'abc-def-ghi::State.32.1.14.16.5',
  1 => 'A',
)

def-ghi::yellow:abc::def:B becomes:

array (
  0 => 'def-ghi::yellow',
  1 => 'abc::def:B',
)
mickmackusa
  • 43,625
  • 12
  • 83
  • 136
0

First split by :: and get both the outputs.
Now, split further output by : and get individual strings.

Finally, append required strings according to your requirements to get exact output:

<?php
  $str = "abc-def-ghi::State.32.1.14.16.5:A";
  $split1 = explode('::', $str)[0];
  $split2 = explode('::', $str)[1];
  $split3 = explode(':', $split2)[0];
  $split4 = explode(':', $split2)[1];
  echo $split1 . "::" . $split3;
  echo $split4;
?>
brasofilo
  • 25,496
  • 15
  • 91
  • 179
Jitesh Sojitra
  • 3,655
  • 7
  • 27
  • 46
0

First explode the string by the delimiter

$x = explode(':', $string) 

Then find the index you need, hopefully $x[2]

Then concatenate the first two.

$first_half = $x[0].$x[1]

Then implode anything after $x[2]

$second_half = implode(':', array_slice($x, 2))
Rápli András
  • 3,869
  • 1
  • 35
  • 55