我有一个文本框,用户可以粘贴一串逗号分隔的数字并将其放入数组中。但是,在某些情况下,该字符串可能包含由破折号分隔的数字,我需要填写该破折号出现的缺失数字。
例子:
1, 4, 7, 20-25, 31, 46, 100
需要变成:
1, 4, 7, 20, 21, 22, 23, 24, 25, 31, 46, 100
我该怎么做呢?间隙不会总是 5 个数字,输入的字符串中可能有不止一组虚线数字。
我有一个文本框,用户可以粘贴一串逗号分隔的数字并将其放入数组中。但是,在某些情况下,该字符串可能包含由破折号分隔的数字,我需要填写该破折号出现的缺失数字。
例子:
1, 4, 7, 20-25, 31, 46, 100
需要变成:
1, 4, 7, 20, 21, 22, 23, 24, 25, 31, 46, 100
我该怎么做呢?间隙不会总是 5 个数字,输入的字符串中可能有不止一组虚线数字。
这是一种方法,没有正则表达式:
这是:
str_getcsv()
以将其分成单独的元素,然后用trim()
和修剪每个元素周围的空白array_map()
。explode()
破折号上的 ing 将它们分隔为开始和结束索引,并在$start
和$end
with之间形成正确的范围range()
。然后,它将新形成的范围与已经形成的范围合并,结果使用array_merge()
.而已!
$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
这可以在不使用正则表达式的情况下完成。
,
作为分隔符展开,您将获得所有数字的数组。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
$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);
,
用分隔符分割字符串explode()
;trim
用;从字符串的开头和结尾删除空格array_map
,因此您无需执行foreach
循环即可应用于trim()
每个元素;foreach
用;遍历每个数字或范围-
,也可以通过分隔符拆分字符串;结果将是一个或多个元素的数组;explode()
-
range()
创建一个包含一系列元素的数组;array_merge()
将新数字存储到第 4 点。带函数的数组;sort()
,因此您没有类似5, 3, 1, 4
等的输出(如果您不需要此功能,请删除此功能);array_unique()
,因此您没有类似4, 4, 4, 4, 5
等的输出(如果您不需要此功能,请删除此功能)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
我的解决方案:在这里演示
str_replace()
explode()
,
用于整数数组的字符串。explode()
每个元素都-
用来检查它是一个范围还是一个整数。range
, 循环使用for()
orrange()
和 add $i
to $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