Самый эффективный способ получить предыдущую букву в алфавите с помощью PHP

Работает отлично:

$str = 'a';
echo ++$str; // prints 'b'

$str = 'z';
echo ++$str; // prints 'aa' 

Очень полезно получить имя следующего столбца в файле Excel.

Но если я использую аналогичный код, используя оператор -- для получения предыдущей буквы, то он не работает:

$str = 'b';
echo --$str; // prints 'b' but I need 'a'

$str = 'aa';
echo --$str; // prints 'aa' but I need 'z'

Каким может быть решение, чтобы получить предыдущее письмо аналогично? И в чем может быть причина, что он не работает?


person itsazzad    schedule 14.10.2014    source источник
comment
С какой культурой и алфавитом? Если вы хотите, создайте круговой связанный список символов в текущем алфавите.   -  person Margus    schedule 14.10.2014
comment
@Margus Предположим, я хочу получить имя предыдущего столбца листа Excel.   -  person itsazzad    schedule 14.10.2014


Ответы (3)


$str='z';
echo chr(ord($str)-1);   //y

Примечание. Это не циркуляр для a-z. Нужно добавить правила для этого

Скрипка

Редактировать Это редактирование соответствует вашим особым требованиям из примера Excel. Хотя это немного более длинный фрагмент кода.

//Step 1: Build your range; We cant just go about every character in every language.

$x='a';
while($x!='zz')         // of course you can take that to zzz or beyond etc
{
  $values[]=$x++;       // A simple range() call will not work for multiple characters
}
$values[]=$x;           // Now this array contains range `a - zz`

//Step 2:  Provide reference
$str='ab';

//Step 3: Move next or back
echo $values[array_search(strtolower($str),$values)-1];   // Previous = aa
echo $values[array_search(strtolower($str),$values)+1];   // Next     = ac

Скрипка

person Hanky Panky    schedule 14.10.2014
comment
Спасибо за это, но мне нужно что-то другое. Как будто он должен охватывать несколько символов - person itsazzad; 14.10.2014
comment
Интересный. Посмотрим, сможем ли мы придумать что-нибудь легкое для этого :) - person Hanky Panky; 14.10.2014

Использование массива:

$cla=array('A', 'B', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 
'P', 'R', 'S', 'Š', 'Z', 'Ž', 'T', 'U', 'V', 'Õ', 'Ä', 'Ö', 'Ü'); 
$direction = -1;
$element = 'Ü';
$element2 = $cla[((array_search($element,$cla)+count($cla)+$direction)%count($cla))]; 
person Margus    schedule 14.10.2014
comment
Обратите внимание, что это односторонний круговой связанный список, купите, возможно, вам понадобится двухсторонний круговой связанный список. Конструкция этого очень похожа, или, поскольку кодировка не меняется, вы можете просто использовать 2 круговых списка с разным порядком. - person Margus; 14.10.2014
comment
Для менее опытного программиста может быть проще использовать массив и изменять указатель, когда он достигает границ. - person Margus; 14.10.2014
comment
Обратите внимание, что это не чувствительный к регистру поиск! Преобразование их в нижний регистр для создания «поиска с учетом регистра» не будет работать для букв умляут. - person Margus; 14.10.2014

Я мог решить таким образом. Как это? Минусы в том, что сейчас он может обрабатывать только верхний регистр. Некоторая дополнительная работа также может исправить это.

<?php
function get_previous_letter($string){
    $last = substr($string, -1);
    $part=substr($string, 0, -1);
    if(strtoupper($last)=='A'){
        $l = substr($part, -1);
        if($l=='A'){
            return substr($part, 0, -1)."Z";
        }
        return $part.chr(ord($l)-1);
    }else{
        return $part.chr(ord($last)-1);
    }
}
echo get_previous_letter("AAAAAA");
?>

CODEPAD

person itsazzad    schedule 14.10.2014
comment
Поскольку AAA не входит в указанный диапазон, сначала вам нужно изменить верхний предел, чтобы включить AAA в этот ответ, как уже упоминалось в комментариях :) - person Hanky Panky; 14.10.2014
comment
Как узнать верхний предел? И не будет ли массив в цикле создавать накладные расходы? Попробуйте использовать zzzzz. Это переполнение стека - person itsazzad; 14.10.2014
comment
Вы должны определить его в соответствии с вашими требованиями. Вы не можете просто включить каждого персонажа. Если zzzzzz является вашим фактическим требованием в Excel, значит, вы анализируете электронную таблицу с миллионами столбцов? Да, любой ненужный диапазон будет использовать всю доступную память. Если ограничений нет, то ваш ответ лучше. - person Hanky Panky; 14.10.2014