我有一个文本框,用户可以粘贴一串逗号分隔的数字,然后将其放入数组中。但是,在某些情况下,该字符串可能包含由短划线分隔的数字,我需要填写短划线出现的缺失数字。
示例:
1, 4, 7, 20-25, 31, 46, 100
需要成为:
1, 4, 7, 20, 21, 22, 23, 24, 25, 31, 46, 100
我该怎么做呢?差距不会总是5个数字,并且输入的字符串中可能有多个虚线数字。
答案 0 :(得分:2)
这是一种没有正则表达式的方法:
是:
str_getcsv()
解析输入字符串,将其分隔为各个元素,然后使用trim()
和array_map()
修剪每个元素周围的空白。explode()
将它们分隔为起始和结束索引,并在$start
和{{1}之间形成正确的范围与range()
。然后,它使用array_merge()
将新形成的范围与已经形成的范围合并。就是这样!
$end
您可以从this demo看到它产生:
$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;
}
}
编辑:要形成结果字符串而不是数组,您只需要调用implode()
,就像这样:
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 )
这将产生:
echo implode( ', ', $result);
答案 1 :(得分:0)
这可以在不使用正则表达式的情况下完成。
,
作为分隔符进行爆炸,您将获得所有数字的数组。 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
<强> See it in action! 强>
答案 2 :(得分: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);
答案 3 :(得分:0)
,
; explode()
拆分字符串
trim
; array_map
函数,因此您无需执行foreach
循环,只需将trim()
应用于每个元素; foreach
; -
与explode()
分开,即使字符串中没有分隔符-
; result将是包含一个或多个元素的数组; range()
创建包含一系列元素的数组; array_merge()
功能的数组; 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
答案 4 :(得分:0)
我的解决方案: DEMO HERE
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