>我有一个文本框,用户可以粘贴一串逗号分隔的数字并将其放入数组中。 但是,在某些情况下,该字符串可能包含由破折号分隔的数字,我需要填写该破折号出现的缺失数字。
例:
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()
将它们分成开始和结束索引,并在$start
和$end
之间形成正确的范围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
$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);
我的解决方案:在这里演示
- 首先使用
str_replace()
删除空格 -
explode()
使用,
到整数数组的字符串。 -
explode()
每个元素使用-
检查它是一个范围还是只是一个整数。 - 如果是
range
,则使用for()
或range()
循环并将$i
添加到$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
简单的代码:
- 用
explode()
分隔符,
分隔字符串; - 用
trim
删除字符串开头和结尾的空格; - 使用函数
array_map
,因此您无需执行foreach
循环即可将trim()
应用于每个元素; - 创建空数组,在其中存储新元素;
- 用
foreach
遍历每个数字或范围; - 在每次迭代中再次执行第 1.、2 和 3 点;
- 通过分隔符拆分字符串
-
explode()
即使字符串中没有分隔符-
; 结果将是具有一个或多个元素的数组; - 如果点 6. 具有包含多个元素的数组,则表示涉及范围,因此使用函数
range()
创建一个包含一系列元素的数组; - 将新数字存储到点 4。 具有
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
这可以在不使用正则表达式的情况下完成。
- 获取用户输入,以
,
作为分隔符爆炸,您将获得所有数字的数组。 - 现在使用
if
语句检查字符串是否包含短划线。 - 如果是这样,请使用分隔符
-
再次explode
。现在你会得到两个数字 - 使用
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
看看它的实际效果!