PHP:是否有一种简单的方法将数字列表(作为字符串,如“1-3,5,7-9”)解析为数组?

PHP:是否有一种简单的方法将数字列表(作为字符串,如“1-3,5,7-9”)解析为数组?,php,arrays,list,methods,numbers,Php,Arrays,List,Methods,Numbers,我试着在这里和谷歌上搜索这个,所以如果我错过了一些明显的东西,我道歉。有可能我根本不知道这些数字的格式名称 我想做的是从一个字符串开始,比如“1-3,5,7-9”,然后将它转换成一个包含以下条目的PHP数组:1,2,3,5,7,8,9 我知道如何通过在逗号上使用preg_split,然后迭代并扩展任意标记来实现这一点,但我觉得必须有一种更简单/更好的方法 编辑 我没有说清楚,但是字符串需要包含跨距!这意味着如果我的字符串是“1-9”,那么我得到的数组应该是“1,2,3,4,5,6,7,8,9”,

我试着在这里和谷歌上搜索这个,所以如果我错过了一些明显的东西,我道歉。有可能我根本不知道这些数字的格式名称

我想做的是从一个字符串开始,比如“1-3,5,7-9”,然后将它转换成一个包含以下条目的PHP数组:1,2,3,5,7,8,9

我知道如何通过在逗号上使用preg_split,然后迭代并扩展任意标记来实现这一点,但我觉得必须有一种更简单/更好的方法

编辑


我没有说清楚,但是字符串需要包含跨距!这意味着如果我的字符串是“1-9”,那么我得到的数组应该是“1,2,3,4,5,6,7,8,9”,而不仅仅是“1,9”。很抱歉,之前还不清楚。

我不知道一种简单的内置方式,因为它不是常见的东西,我怀疑是否有内置的东西


你描述的方式听起来很合理。只需对字符串进行一次迭代就可以做到这一点,但除非这是一个已知的性能问题,否则我不会为此费心。

不完全确定“扩展”是什么意思。不管怎样,以下是我将如何使用和:

如果有更好的方法不使用
eval
(或PCRE
e
修饰符),我也不知道

这是一个单行程序(不幸地使用了
eval
),返回相同的结果,但是

免责声明:在大多数情况下不建议使用
eval
,因为它可能会产生安全风险和其他问题我不会使用它,但它仍然可行

话虽如此,这就是:

$output = explode(',', preg_replace('/([0-9]*)-([0-9]*)/e', 'implode(",", range($1, $2));', $input));

不确定这有多高效,但它完成了任务。

去做这件事,我回来看到了两个答案:(


上述例行程序运行良好,但有一些缺点:

  • 字符串中的空格打乱了例程
  • 未删除重复项,例如5,4-7给出5,4,5,6,7
  • 数字没有排序
  • 我已更改代码以解决这些问题:

    function parsenumbers($input)
    {
        /*
         * This routine parses a string containing sets of numbers such as:
         * 3
         * 1,3,5
         * 2-4
         * 1-5,7,15-17
         * spaces are ignored
         * 
         * routine returns a sorted array containing all the numbers
         * duplicates are removed - e.g. '5,4-7' returns 4,5,6,7
         */
        $input = str_replace(' ', '', $input); // strip out spaces
        $output = array();
        foreach (explode(',', $input) as $nums)
        {
            if (strpos($nums, '-') !== false)
            {
                list($from, $to) = explode('-', $nums);
                $output = array_merge($output, range($from, $to));
            }
            else
            {
                $output[] = $nums;
            }
        }
    
        $output = array_unique($output, SORT_NUMERIC); // remove duplicates
        sort($output);
    
        return $output;
    }
    

    你看了explode?我很高兴这里的每个人都仔细阅读了这个问题…我编辑了这篇文章…我的问题是跨度,比如“1-5”需要“1,2,3,4,5”,而不仅仅是“1,5”我认为这很清楚,但显然@animunson是唯一一个注意到的人:p+1我肯定忽略了跨距,将它们视为分隔符。功能很好,谢谢。如果我可以添加我的分。
    $output[]=$nums;
    返回一个字符串,我将其更改为
    $output[]=$nums+0;
    以获取所有整数。
    $str = '1-3,5,7-9';
    $arr = explode(',', $str);
    $result = array();
    foreach($arr as $a){
      $x = explode('-', $a);
      if(count($x) === 2){
        $x = range($x[0], $x[1]);
      }
      $result = array_merge($result, $x);
    }
    print_r($result);
    
    <?php
    function arrex($s){
        $arr = explode("-", $s);
        $v=$arr[0] + 1;
        $val = array();
                while($v!=$arr[1]){
                     $val[$v] = $v;
                       $v++;
                }
        array_unshift($val, $arr[0]);
        array_push($val, $arr[1]);
    return $val;
    }
    $s = "1-9";
    print_r(arrex($s));
    ?>
    
    Array
    (
        [0] => 1
        [1] => 2
        [2] => 3
        [3] => 4
        [4] => 5
        [5] => 6
        [6] => 7
        [7] => 8
        [8] => 9
    )
    
    function parsenumbers($input)
    {
        /*
         * This routine parses a string containing sets of numbers such as:
         * 3
         * 1,3,5
         * 2-4
         * 1-5,7,15-17
         * spaces are ignored
         * 
         * routine returns a sorted array containing all the numbers
         * duplicates are removed - e.g. '5,4-7' returns 4,5,6,7
         */
        $input = str_replace(' ', '', $input); // strip out spaces
        $output = array();
        foreach (explode(',', $input) as $nums)
        {
            if (strpos($nums, '-') !== false)
            {
                list($from, $to) = explode('-', $nums);
                $output = array_merge($output, range($from, $to));
            }
            else
            {
                $output[] = $nums;
            }
        }
    
        $output = array_unique($output, SORT_NUMERIC); // remove duplicates
        sort($output);
    
        return $output;
    }