Search code examples
phparraysintegerrangetext-parsing

Populate array of integers from a comma-separated string of numbers and hyphenated number ranges


I want to translate/hydrate/expand/parse a comma-separated string of integers and hyhenated integer range expressions and populate an array with its equivalent values as individual integers elements.

Input strings might look like the following:

3,5,6,9,11,23

or

3-20

or

3-6,8,12,14-20

I want to return these as an array of integers, so the last one would become:

[3,4,5,6,8,12,14,15,16,17,18,19,20]

Is there either a function available that does this, or how would I start in writing one?


Solution

  • You are probably looking for the range function and implode:

    $input = '3,5,6,9,11,23,14-77';
    
    $result = preg_replace_callback('/(\d+)-(\d+)/', function($m) {
        return implode(',', range($m[1], $m[2]));
    }, $input);
    

    gives you:

    3,5,6,9,11,23,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77
    

    Demo

    How it works: You basically have two tokens in your string: the range-token (1-n) (defined as regular expression: (\d+)-(\d+)) and the fallback (anything else).

    preg_replace_callback allows the expansion of the token string by a callback function. That callback function then just expands the two matched numerical values into the comma-separated list by using PHP's range function and implode.

    After that the string is in a normalized format you can just explode it:

    // as array:
    
    print_r(explode(',', $result));
    

    Full Demo


    And after years as it was requested well formulated, the integer array, you can easily treat it as a JSON Array:

    $result = json_decode('['. preg_replace_callback('/(\d+)-(\d+)/', function($m) {
        return implode(',', range($m[1], $m[2]));
    }, $input) .']');
    var_dump($result);
    

    Demo PHP 5.3-8.1 + Git Master