1

我有一个文本框,用户可以粘贴一串逗号分隔的数字并将其放入数组中。但是,在某些情况下,该字符串可能包含由破折号分隔的数字,我需要填写该破折号出现的缺失数字。

例子:

1, 4, 7, 20-25, 31, 46, 100

需要变成:

1, 4, 7, 20, 21, 22, 23, 24, 25, 31, 46, 100

我该怎么做呢?间隙不会总是 5 个数字,输入的字符串中可能有不止一组虚线数字。

4

5 回答 5

2

这是一种方法,没有正则表达式:

这是:

  1. 用 解析输入字符串str_getcsv()以将其分成单独的元素,然后用trim()和修剪每个元素周围的空白array_map()
  2. 遍历每个元素,搜索破折号。如果它找到一个破折号,它就找到了一个数字范围,因此它通过explode()破折号上的 ing 将它们分隔为开始和结束索引,并在$start$endwith之间形成正确的范围range()。然后,它将新形成的范围与已经形成的范围合并,结果使用array_merge().
  3. 如果在迭代过程中没有找到破折号,则假定您有一个文字数字,并将该数字添加到结果数组中。

而已!

$input = '1, 4, 7, 20-25, 31, 46, 100';
$entries = array_map( 'trim', str_getcsv( $input));

$result = array();
foreach( $entries as $entry) {
    if( strpos( $entry, '-') !== false) {
        list( $start, $end) = explode( '-', $entry);
        $result = array_merge( $result, range( trim($start), trim($end)));
    } else {
        $result[] = $entry;
    }
}

您可以从这个演示中看到它产生:

Array (
    [0] => 1
    [1] => 4
    [2] => 7
    [3] => 20
    [4] => 21
    [5] => 22
    [6] => 23
    [7] => 24
    [8] => 25
    [9] => 31
    [10] => 46
    [11] => 100 )

编辑:要形成结果字符串,而不是数组,您只需要调用implode(),如下所示:

echo implode( ', ', $result);

这将产生:

1, 4, 7, 20, 21, 22, 23, 24, 25, 31, 46, 100
于 2013-09-11T19:06:39.047 回答
0

这可以在不使用正则表达式的情况下完成。

  • 获取用户输入,以,作为分隔符展开,您将获得所有数字的数组。
  • 现在使用if语句来检查字符串是否包含破折号。
  • 如果是,explode则再次使用 delimiter -。现在你会得到两个数字
  • 用于range()创建该范围内的数字数组
  • 使用implode()逗号加入它们。

作为一个有用的功能:

代码:

function fill_string_gaps($input) 
{
    $parts = explode(',', $input);
    $resultArray = array();

    foreach ($parts as $part) {
        if(strpos(trim($part), '-')) {
            list($num1, $num2) = explode('-', $part);
            $expanded_num_array = range($num1, $num2);
            $resultArray = array_merge($resultArray, $expanded_num_array);
        } else {
            $resultArray[] = trim($part);
        }        
    }
        $comma_separated = implode(', ', $resultArray);
        return $comma_separated;

}

用法:

$input = '1, 4, 7, 20-25, 31, 46, 100';
echo fill_string_gaps($input;)

测试用例:

echo fill_string_gaps('1-5');
echo fill_string_gaps('1-5, 12, 24');
echo fill_string_gaps('2, 2, 4, 5-8');

输出:

1, 2, 3, 4, 5
1, 2, 3, 4, 5, 12, 24
2, 2, 4, 5, 6, 7, 8

在行动中看到它!

于 2013-09-11T19:04:18.827 回答
0
$data = '1, 4, 7, 20-25, 31, 46, 100';
$elts = explode(',', $data);
$res = array();

foreach ($elts as $elt) {
    $elt = trim($elt);

    if (preg_match('/(\d+)-(\d+)/', $elt, $matches) === 1) {
        $res = array_merge($res, range($matches[1], $matches[2]));
    } else {
        $res[] = intval($elt);
    }
}

var_dump($res);
于 2013-09-11T19:04:54.983 回答
0

简单的代码:

  1. ,用分隔符分割字符串explode()
  2. trim用;从字符串的开头和结尾删除空格
  3. 使用函数array_map,因此您无需执行foreach循环即可应用于trim()每个元素;
  4. 创建空数组,您将在其中存储新元素;
  5. foreach用;遍历每个数字或范围
  6. 在每次迭代中再次执行第 1.、2. 和 3. 点;
  7. 即使字符串中没有分隔符-,也可以通过分隔符拆分字符串;结果将是一个或多个元素的数组;explode()-
  8. 如果第 6 点有多个元素的数组,这意味着涉及范围,因此使用函数range()创建一个包含一系列元素的数组;
  9. array_merge()将新数字存储到第 4 点。带函数的数组;
  10. 当第 4 点完全生成数组时;使用 对值进行排序sort(),因此您没有类似5, 3, 1, 4等的输出(如果您不需要此功能,请删除此功能);
  11. 删除重复项array_unique(),因此您没有类似4, 4, 4, 4, 5等的输出(如果您不需要此功能,请删除此功能)
  12. 要将数组转换回您输入的字符串,请使用implode()函数。

|

function fillGaps($s) {
    $s = array_map('trim', explode(',', $s));
    $ss = [];
    foreach ($s as $n) {
        $n = array_map('trim', explode('-', $n));
        if (count($n) > 1) $n = range($n[0], end($n));
        $ss = array_merge($ss, $n);
    }
    sort($ss); # remove if you don't need sorting
    $ss = array_unique($ss); # remove if duplicates are allowed
    return implode(', ', $ss);
}

例子 :

你的例子:

echo fillGaps('1,    4, 7, 20   -   25, 31, 46, 100');
# 1, 4, 7, 20, 21, 22, 23, 24, 25, 31, 46, 100

此代码也适用于多个间隙,例如:

echo fillGaps('100-105-110');
# 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110

你甚至可以反过来:

echo fillGaps('10-5');
# 5, 6, 7, 8, 9, 10
# or remove function sort() and output will be 10, 9, 8, 7, 6, 5

删除重复项:

echo fillGaps('2-4, 4, 4, 5');
# 2, 3, 4, 5
于 2013-09-11T19:10:13.010 回答
0

我的解决方案:在这里演示

  • 首先使用删除空格str_replace()
  • explode(),用于整数数组的字符串。
  • explode()每个元素都-用来检查它是一个范围还是一个整数。
  • 如果是range, 循环使用for()orrange()和 add $ito $newArray,否则将元素添加到$newArray.
  • implode()使用,并打印结果。

PHP代码:

<?php
       $str=str_replace(' ', '', '1, 4, 7, 20-25, 31, 46, 100');
       $arr = explode(',',$str);
        foreach($arr as $elem){
           $values=explode('-',$elem);
          if(count($values)!=1)  for($i=$values[0];$i<=$values[1];$i++)   $newArr[]=$i;
          else $newArr[]=$elem;
        }
       echo implode(',',$newArr);
?>

输出:

1,4,7,20,21,22,23,24,25,31,46,100
于 2013-09-11T19:31:16.103 回答