带分隔符的Php字符串到页面列表


Php string with separator to page list

我试图重现我们在office或adobe上打印页面时看到的效果。

例如,当你想打印第1页到第5页时,你写:1-5,如果你想打印外面的一页,你写:1-5,8

现在我爆炸string by ',':1-5/8

然后用'-'把每个结果分开,如果我得到了结果,我就从第一页循环到最后一页,并用逗号创建变量:

1、2、3、4、5、8

最后我用',',并使用数组唯一来擦除双精度值。

实现这一点需要一些时间,特别是当有很多'-'时。

也许有人有更简单的解决方法?

谢谢编辑:

$pages = "1-4,6-8,14,16,18-20";
$pages_explode = explode(',',$pages);
foreach($pages_explode as $page){
$page_explode = explode('-',$page);
if(!empty($page_explode[1])){
for ($i=$page_explode[0]; $i<=$page_explode[1] ; $i++) {
$page_final .= $i.',';
}
}else{
$page_final .= $page_explode[0].',';
}
}
$page_final = explode(',',$page_final);
$page_final = array_unique ($page_final);
foreach($page_final as $value){
echo $value.'<br>';
}

这是一个代码高尔夫挑战吗?

一个基本的方法对我来说似乎很好:

$input = '1-5,6-12,8';
$patterns = explode(',', $input);
$pages = [];
foreach ($patterns as $pattern) {
    if (2 == count($range = explode('-', $pattern))) {
        $pages = array_merge($pages, range($range[0], $range[1]));
    } else {
        $pages[] = (int)$pattern;
    }
}
$uniquePages = array_unique($pages);
var_dump($uniquePages);

输出:

array (size=12)
  0 => int 1
  1 => int 2
  2 => int 3
  3 => int 4
  4 => int 5
  5 => int 6
  6 => int 7
  7 => int 8
  8 => int 9
  9 => int 10
  10 => int 11
  11 => int 12

必须删除重复项表明您的字符串中有重叠的范围。

如:1 - 5、2 - 9、7 - 15,8 10

你似乎处理了所有这些而没有考虑重叠的区域,最后试图通过昂贵的array_unique函数删除重复项。

您的代码应该记住结果范围的最小值和最大值,而不处理任何与此范围重叠的内容。

下面是演示这个想法的示例代码。但它肯定比你在你的问题中建议的代码快。您应该在那里添加部分,以处理需求中其他类型的分隔符(如果有的话)。

<?php
$ranges = "1-5,3-7,6-10,8,11";  
$min = 10000;
$max = -1;    
$numbers = array();     //Your numbers go here

//Just a utility function to generate numbers from any range and update margins
function generateNumbers($minVal, $maxVal) {
    global $min, $max, $numbers;
    for ($i = $minVal; $i <= $maxVal; $i++) {
        array_push($numbers, $i);
        if ($i < $min)
            $min = $i;
        if ($i > $max)
            $max = $i;
    }

}    

//Seperate ranges
$sets = explode(",", $ranges);
//Go through each range
foreach($sets as $aSet) {
    //Extract the range or get individual numbers
    $range = explode("-", $aSet);   
    if (count($range) == 1)  { //its an individual number. So check margins and insert
        $aSet = intval($aSet);
        if ($aSet < $min){ 
            array_push($numbers, $aSet);
            $min = $aSet;
        }       
        if ($aSet > $max){ 
            array_push($numbers, $aSet);
            $max = $aSet;
        }       
        continue;       // <----- For single numbers it ends here
    }       

    //Its a range
    $rangeLow = intval($range[0]);
    $rangeHigh = intval($range[1]);

    //Adjusting numbers to omit cases when ranges fall right on the margins
    if ($rangeLow == $min){
        $rangeLow++;
    }
    else
        if ($rangeLow == $max) {
        $rangeLow--;
    }
    if ($rangeHigh == $min){
        $rangeHigh++;
    }
    else
        if ($rangeHigh == $max) {
        $rangeHigh--;
    }   

    //Check if below or above the generated range
    if (($rangeLow < $min && $rangeHigh < $min) || ($rangeLow > $max && $rangeHigh > $max)) {
        generateNumbers($rangeLow, $rangeHigh);
    };

    //Check if across the lower edge of the generated range
    if ($rangeLow < $min && $rangeHigh > $min && $rangeHigh < $max) {
        generateNumbers($rangeLow, $min - 1);
    };

    //Check if across the upper edge of the generated range
    if ($rangeLow > $min && $rangeLow < $max && $rangeHigh > $max) {
        generateNumbers($max + 1, $rangeHigh);
    };  
}

//Now just sort the array
print_r($numbers);
?>