2

How can I split this string of comma-separated dimensions into two arrays? The string may have many items in it, but it will always have the same two alternating delimiters (exes and commas).

$str = "20x9999,24x65,40x5";

I need to get two arrays from this string:

$array1 = [20, 24, 40];
$array2 = [9999, 65, 5];

I've tried many implementations of preg_split(), array_slice(), and regex. I can't get it done.

mickmackusa
  • 43,625
  • 12
  • 83
  • 136

3 Answers3

3

You can explode the string by commas, and then explode each of those values by x, inserting the result values from that into the two arrays:

$str = "20x9999,24x65,40x5";

$array1 = array();
$array2 = array();
foreach (explode(',', $str) as $key => $xy) {
    list($array1[$key], $array2[$key]) = explode('x', $xy);
}

Alternatively, you can use preg_match_all, matching against the digits either side of the x:

preg_match_all('/(\d+)x(\d+)/', $str, $matches);
$array1 = $matches[1];
$array2 = $matches[2];

In both cases the output is:

Array
(
    [0] => 20
    [1] => 24
    [2] => 40
)
Array
(
    [0] => 9999
    [1] => 65
    [2] => 5
)

Note that as of PHP7.1, you can use array destructuring instead of list, so you can just write

[$array1[$key], $array2[$key]] = explode('x', $xy);

instead of

list($array1[$key], $array2[$key]) = explode('x', $xy);

You can use this to simplify the assignment of the result from preg_match_all as well:

[, $array1, $array2] = $matches;

Demo on 3v4l.org

Nick
  • 138,499
  • 22
  • 57
  • 95
0

I guess with preg_split, we could do so:

$str = '20x9999,24x65,40x5';

$array1 = $array2 = array();

foreach (preg_split("/,/", $str, -1, PREG_SPLIT_NO_EMPTY) as $key => $value) {
    $val = preg_split("/x/", $value, -1, PREG_SPLIT_NO_EMPTY);
    array_push($array1, $val[0]);
    array_push($array2, $val[1]);
}

var_dump($array1);
var_dump($array2);

Output

array(3) {
  [0]=>
  string(2) "20"
  [1]=>
  string(2) "24"
  [2]=>
  string(2) "40"
}
array(3) {
  [0]=>
  string(4) "9999"
  [1]=>
  string(2) "65"
  [2]=>
  string(1) "5"
}
Community
  • 1
  • 1
Emma
  • 27,428
  • 11
  • 44
  • 69
0

Parsing the comma-separated, then x-delimited sets of data into separate arrays with integer-typed values can be direct achieved by iterating over a comma-exploded array, then making sscanf() calls with %d placeholders

For other scenarios, use %f for floats, %s to greedily match consecutive visible characters, and [^,], [^x], etc to match continuous characters not in the list.

Code: (Demo)

$one = [];
$two = [];
foreach (explode(',', $str) as $set) {
    sscanf($set, '%dx%d', $one[], $two[]);
}
var_dump($one, $two);

Output with int typed values:

array(3) {
  [0] => int(20)
  [1] => int(24)
  [2] => int(40)
}
array(3) {
  [0] => int(9999)
  [1] => int(65)
  [2] => int(5)
}

Extending the sample data format to have values which contain delimiting characters, str_getcsv() can be rather handy. Consider the following parse&split approach to preserve the double quoted substring -- which is the natural syntax that a .csv file would use.

Code: (Demo)

$str = '"20x9,999",24x65,40x5';
//           ^------------------ don't split on this comma and omit the double quotes
$one = [];
$two = [];
foreach (str_getcsv($str) as $set) {
    [$one[], $two[]] = explode('x', $set);
}
var_dump($one, $two);

Choose a combination of these techniques depending on your input and desired output for real world tasks where nested splitting is needed.

mickmackusa
  • 43,625
  • 12
  • 83
  • 136