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

Format string including alphabetic and numeric charaters

我在 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;
    }
}
}

这是您可以做到的。
在第一个 foreach 中,您构建了一个 多维数组 ,其中字母作为键,数字在其中。在第二个循环中,您构建了另一个数组,其中包含一个带有字母和 min/max 值 的字符串。然后你通过字母订购并加入他们:

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

文档:

下面是此代码的解决方案: 要对其进行测试,请访问此页面: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);