格式化字符串,包括字母和数字字符

时间:2018-08-09 09:11:17

标签: php string pagination string-formatting

我在php中有一个这样的字符串

A14,A15,B13,B14,B15,B16,B17,B18,B19,B20,B21,B22,B23,B24,B25,B26
我要转换为的

A14,A15;B13-B26

我有分页的解决方案,但不适用于包含数字和字母字符的字符串。

另一个例子是

E18,E19,E20,E21,E22,E23,E24,E25,E26,F18,F19,F20,F21,F22,F23,F24,F25,F26

E18-E26;F18-F26

当前的代码有点困难,无法正常工作,我正在寻找一种更简单的方法

$shelves = "A14,A15,B13,B14,B15,B16,B17,B18,B19,B20,B21,B22,B23,B24,B25,B26";

function simplify_shevlves_text ($shelves) {
$simplified_string = "";
$next_number = 0;
$next_alphabet = "";
$next_string = "";

if(!empty($shelves)) {
    $exploded_shelves = explode(",", $shelves);
    if(count($exploded_shelves) == 1) {
        return $shelves;
    }
    else {
        foreach($exploded_shelves as $single_shelve) {

            //echo "NEXT NUMBER: " . $next_number . "<br>";
            //echo "NEXT ALPHABET: " . $next_alphabet . "<br>";

            $single_shelve = trim($single_shelve);
            if(empty($next_string)) {
                $next_string = $single_shelve;
            }

            if(empty($simplified_string)){
                $simplified_string = $single_shelve;
            }

            $shelve_alphabet = substr($single_shelve, 0, 1);
            //echo "ALPHABET: " . $shelve_alphabet . "<br>";
            $number = substr($single_shelve, 1);
            //echo "NUMBER: " . $number . "<br>";

            if($next_string == $single_shelve) {
                $simplified_string = rtrim($simplified_string, "-");
                $simplified_string .= "-" . $single_shelve;
            }
            else {
                $simplified_string .= ";" . $single_shelve;
            }


            $next_number = (int) $number + 1;
            $next_alphabet = $shelve_alphabet;
            $next_string = $next_alphabet . $next_number;
            echo "SIMPLIFIED STRING: " . $simplified_string . "<br>";
            echo "NEXT STRING: " . $next_string . "<br>";
            //echo "NEXT NUMBER: " . $next_number . "<br>";
            //echo "NEXT ALPHABET: " . $next_alphabet . "<br>";
        }

        $shelve_alphabet = substr($shelves, 0, 1);
        return $simplified_string;
    }
}
}

2 个答案:

答案 0 :(得分:1)

这是您的操作方法。
在第一个foreach中,您将构建一个多维数组,其中字母为键,数字为内部。在第二个循环中,您将构建另一个数组,该数组包含带有字母和 min / max values 的字符串。然后您通过信件订购它们并加入它们:

function simplify_shevlves_text($shelves)
{
    // Removes gaps between data
    $shelves = str_replace(' ', '', $shelves);

    // Group numbers by letters (multidimensionnal array)
    $letters = [];
    foreach (explode(',', $shelves) as $part) {
        $letters[substr($part, 0, 1)][] = substr($part, 1);
    }

    // Ordering
    ksort($letters);

    // Strings with MIN-MAX values
    $min_max = [];
    foreach ($letters as $l => $v) {
        $min_max[] = $l . min($v) . '-' . $l . max($v);
    }

    return implode(';', $min_max);
}

通过第一个循环和排序,您甚至可以发送无序字符串:

//     |                       B                           |   A   |   B    |
$str = 'B13,B 14,B15,B16,B17, B20,B21,B22,B23,B 24,B25, B26,A14,A15,B18,B19';

echo simplify_shevlves_text($str);
// A14-A15;B13-B26

文档:

答案 1 :(得分:1)

以下是此代码的解决方案: 要对其进行测试,请访问以下页面:http://sandbox.onlinephpfunctions.com/code/038229a99c67c7dce95935865e5c0dafa65061b2

<?php

$string = "A14,A15,A18,A19,A20,A21,B13,B14,B15,B16,B17,B18,B19,B20,B21,B22,B23,B24,B25,B26";

$values = explode(",", $string);

$sorting = [];
foreach ($values as $value) {
    $currentVal = substr($value, 1);
    $currentLetter = $value[0];

    // Letter is not already tracked initialise it
    if(!isset($sorting[$currentLetter])) {
        $sorting[$currentLetter] = [
            // Meta tracks current progress for letter
            "meta" => 1,
            1 => [
                "start" => substr($value, 1),
                "end" => substr($value, 1)
            ]
        ];
        continue;
    }

    $currentMeta = $sorting[$currentLetter]["meta"];

    if($sorting[$currentLetter][$currentMeta]["end"] + 1 == $currentVal) {
        // Letter exists and new value is in range to continue the row, so increase the end of current row
        $sorting[$currentLetter][$currentMeta]["end"] = $currentVal;
    } else {
        // Letter exists and new value has a gap to the last row, create new row with default values
        $currentMeta++;
        $sorting[$currentLetter]["meta"] = $currentMeta;
        $sorting[$currentLetter][$currentMeta] = [
            "start" => $currentVal,
            "end" => $currentVal
        ];
    }
}

// Output formatting
$output_string = "";
foreach ($sorting as $letter => $ranges) {
    foreach($ranges as $key => $range) {
        if($key == "meta") continue;

        if ($range["start"] == $range["end"]) {
            $output_string .= "{$letter}{$range["start"]};";
            continue;
        }
        $output_string .= "{$letter}{$range["start"]}-{$letter}{$range["end"]};";
    }
}

$output_string = trim($output_string, ";");
var_dump($output_string);