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