将整数转换为字母,反之亦然(例如 0 =“A”、26 =“AA”、27 =“AB”)

发布于 2024-12-08 04:07:16 字数 1494 浏览 0 评论 0原文

所以我有这个函数:

function toAlpha($data){
    $alphabet =   array('a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z');
    $alpha_flip = array_flip($alphabet);
    if($data <= 25){
      return $alphabet[$data];
    }
    elseif($data > 25){
      $dividend = ($data + 1);
      $alpha = '';
      $modulo;
      while ($dividend > 0){
        $modulo = ($dividend - 1) % 26;
        $alpha = $alphabet[$modulo] . $alpha;
        $dividend = floor((($dividend - $modulo) / 26));
      } 
      return $alpha;
    }
}

给定一个数字将其转换为字符并且工作正常,

但是我还想要一个该函数的反向函数,给定该函数的任何输出,返回为产生该输出而输入的确切输入,然后我尝试过这个:

function toNum($data){
$alphabet =   array('a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z');
    $alpha_flip = array_flip($alphabet);
  if(strlen($data) == 1){
          return (isset($alpha_flip[$data]) ? $alpha_flip[$data] : FALSE);
        }
        else if(strlen($data) > 1){
          $num = 1;
          for($i = 0; $i < strlen($data); $i++){
            if(($i + 1) < strlen($data)){
              $num *= (26 * ($alpha_flip[$data[$i]] + 1));
            }
            else{
              $num += ($alpha_flip[$data[$i]] + 1);
            }
          }
          return ($num + 25);
        }
}

但它无法正常工作...toAlpha(728) 正在生成 'aba' 但 toNum('aba') 正在生成 1378 而不是 728...

我做错了什么?如何修复反向功能使其正常工作?

So I have this function:

function toAlpha($data){
    $alphabet =   array('a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z');
    $alpha_flip = array_flip($alphabet);
    if($data <= 25){
      return $alphabet[$data];
    }
    elseif($data > 25){
      $dividend = ($data + 1);
      $alpha = '';
      $modulo;
      while ($dividend > 0){
        $modulo = ($dividend - 1) % 26;
        $alpha = $alphabet[$modulo] . $alpha;
        $dividend = floor((($dividend - $modulo) / 26));
      } 
      return $alpha;
    }
}

which given a number converts it into character and it works fine

but then I also want a reverse function of this that given any output of this function, return the exact input that was put in to produce that output and I tried this:

function toNum($data){
$alphabet =   array('a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z');
    $alpha_flip = array_flip($alphabet);
  if(strlen($data) == 1){
          return (isset($alpha_flip[$data]) ? $alpha_flip[$data] : FALSE);
        }
        else if(strlen($data) > 1){
          $num = 1;
          for($i = 0; $i < strlen($data); $i++){
            if(($i + 1) < strlen($data)){
              $num *= (26 * ($alpha_flip[$data[$i]] + 1));
            }
            else{
              $num += ($alpha_flip[$data[$i]] + 1);
            }
          }
          return ($num + 25);
        }
}

but it's not working properly...toAlpha(728) is producing 'aba' but toNum('aba') is producing 1378 rather than 728...

What did I do wrong? How can I fix the reverse function so that it works properly?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

怪我入戏太深 2024-12-15 04:07:17

最短的方法,在 PHP >= 4.1.0

$alphabet = range('A', 'Z');

echo $alphabet[3]; // returns D

echo array_search('D', $alphabet); // returns 3

Shortest way, in PHP >= 4.1.0

$alphabet = range('A', 'Z');

echo $alphabet[3]; // returns D

echo array_search('D', $alphabet); // returns 3
故乡的云 2024-12-15 04:07:17

我完全不明白你试图在该函数中使用的逻辑。你想要做的事情看起来很奇怪(为什么'a'映射到零而'aa'映射到26?),但这似乎有效。 (您将需要使用更多测试用例,我只检查它是否为案例“aba”提供了正确的输出。)

function toNum($data) {
    $alphabet = array( 'a', 'b', 'c', 'd', 'e',
                       'f', 'g', 'h', 'i', 'j',
                       'k', 'l', 'm', 'n', 'o',
                       'p', 'q', 'r', 's', 't',
                       'u', 'v', 'w', 'x', 'y',
                       'z'
                       );
    $alpha_flip = array_flip($alphabet);
    $return_value = -1;
    $length = strlen($data);
    for ($i = 0; $i < $length; $i++) {
        $return_value +=
            ($alpha_flip[$data[$i]] + 1) * pow(26, ($length - $i - 1));
    }
    return $return_value;
}

I don't understand at all the logic you're trying to use in that function. What you're trying to do seems very strange (why does 'a' map to zero and yet 'aa' maps to 26?), but this appears to work. (You will want to use some more test cases, I only checked that it gives the correct output for the case 'aba'.)

function toNum($data) {
    $alphabet = array( 'a', 'b', 'c', 'd', 'e',
                       'f', 'g', 'h', 'i', 'j',
                       'k', 'l', 'm', 'n', 'o',
                       'p', 'q', 'r', 's', 't',
                       'u', 'v', 'w', 'x', 'y',
                       'z'
                       );
    $alpha_flip = array_flip($alphabet);
    $return_value = -1;
    $length = strlen($data);
    for ($i = 0; $i < $length; $i++) {
        $return_value +=
            ($alpha_flip[$data[$i]] + 1) * pow(26, ($length - $i - 1));
    }
    return $return_value;
}
千柳 2024-12-15 04:07:17

Theriault 在 PHPs base_convert 函数 的评论中有一个非常聪明的解决方案

/**
* Converts an integer into the alphabet base (A-Z).
*
* @param int $n This is the number to convert.
* @return string The converted number.
* @author Theriault
* 
*/
function num2alpha($n) {
    $r = '';
    for ($i = 1; $n >= 0 && $i < 10; $i++) {
    $r = chr(0x41 + ($n % pow(26, $i) / pow(26, $i - 1))) . $r;
    $n -= pow(26, $i);
    }
    return $r;
}
/**
* Converts an alphabetic string into an integer.
*
* @param int $n This is the number to convert.
* @return string The converted number.
* @author Theriault
* 
*/
function alpha2num($a) {
    $r = 0;
    $l = strlen($a);
    for ($i = 0; $i < $l; $i++) {
    $r += pow(26, $i) * (ord($a[$l - $i - 1]) - 0x40);
    }
    return $r - 1;
}

There is a very clever solution by Theriault in the comments of PHPs base_convert function

/**
* Converts an integer into the alphabet base (A-Z).
*
* @param int $n This is the number to convert.
* @return string The converted number.
* @author Theriault
* 
*/
function num2alpha($n) {
    $r = '';
    for ($i = 1; $n >= 0 && $i < 10; $i++) {
    $r = chr(0x41 + ($n % pow(26, $i) / pow(26, $i - 1))) . $r;
    $n -= pow(26, $i);
    }
    return $r;
}
/**
* Converts an alphabetic string into an integer.
*
* @param int $n This is the number to convert.
* @return string The converted number.
* @author Theriault
* 
*/
function alpha2num($a) {
    $r = 0;
    $l = strlen($a);
    for ($i = 0; $i < $l; $i++) {
    $r += pow(26, $i) * (ord($a[$l - $i - 1]) - 0x40);
    }
    return $r - 1;
}
看轻我的陪伴 2024-12-15 04:07:17

从数字到字母(A=0、B=1 等):

function toAlpha($num){
    return chr(substr("000".($num+65),-3));
}

您可以使用函数 ord() 从字母到数字执行相同的操作。

将65改为97,即可得到小写值。

From number to alphabet (with A=0, B=1, etc...):

function toAlpha($num){
    return chr(substr("000".($num+65),-3));
}

You can do the same from alphabet to number with the function ord().

Changing 65 with 97, you can obtain the lowercase values.

蒲公英的约定 2024-12-15 04:07:17

你的问题来自你的地图。看看这个:

$alpha[0] = 'Alphabet';
for ($i = 'a'; $i<'z'; $i++) {
    $alpha[] = $i;
}
$alpha[26] = 'z';

您可以在服务器内存允许的情况下运行任意高的值。 PHP 是有缺陷的,并且(至少在我的服务器上)如果您使用 <= 运算符:

$alpha[0] = 'Alphabet';
for ($i = 'a'; $i<='z'; $i++) {
    $alpha[] = $i;
}

那么它将一直映射到 [676]==>字符串(2)“yz”!你只需要玩它。

我不想将字母映射到 [0],所以我只是在其中放置了一个标题。显然,如果您想要 0=>a、1=>b 等,则可以将其省略。

一旦数组正确,该函数就很简单了。

Your problems comes from your map. Look at this:

$alpha[0] = 'Alphabet';
for ($i = 'a'; $i<'z'; $i++) {
    $alpha[] = $i;
}
$alpha[26] = 'z';

You can run this as high as you want and your server memory will allow. The PHP is buggy, and (at least on my server) if you use the <= operator:

$alpha[0] = 'Alphabet';
for ($i = 'a'; $i<='z'; $i++) {
    $alpha[] = $i;
}

then it will map all the way to [676]=> string(2) "yz"! You just have to play with it.

I didn't want to map a letter to [0] so I just put a title in there. Obviously you can leave it out if you want 0=>a, 1=>b, etc.

Once the array is correct, the function is trivial.

仙气飘飘 2024-12-15 04:07:17

使用西里尔的回答,我对一个包含多个字母的案例进行了一些详细说明。

function lettersToNumber($letters){
    $alphabet = range('A', 'Z');
    $number = 0;

    foreach(str_split(strrev($letters)) as $key=>$char){
        $number = $number + (array_search($char,$alphabet)+1)*pow(count($alphabet),$key);
    }
    return $number;
}

下面显示了该函数的一些结果:

lettersToNumber("A"); //returns 1
lettersToNumber("E"); //returns 5
lettersToNumber("Z"); //returns 26
lettersToNumber("AB"); //returns 28
lettersToNumber("AP"); //returns 42
lettersToNumber("CE"); //returns 83

Using Cyril's answer, I elaborated a bit for a case with more than one letter.

function lettersToNumber($letters){
    $alphabet = range('A', 'Z');
    $number = 0;

    foreach(str_split(strrev($letters)) as $key=>$char){
        $number = $number + (array_search($char,$alphabet)+1)*pow(count($alphabet),$key);
    }
    return $number;
}

A few results for the function are displayed bellow:

lettersToNumber("A"); //returns 1
lettersToNumber("E"); //returns 5
lettersToNumber("Z"); //returns 26
lettersToNumber("AB"); //returns 28
lettersToNumber("AP"); //returns 42
lettersToNumber("CE"); //returns 83
梦回梦里 2024-12-15 04:07:17

将数字转换为字母代码

例如:1402 转 bax

function number_to_alpha($num, $code)
{   
    $alphabets = array('', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z');

    $division = floor($num / 26);
    $remainder = $num % 26; 

    if($remainder == 0)
    {
        $division = $division - 1;
        $code .= 'z';
    }
    else
        $code .= $alphabets[$remainder];

    if($division > 26)
        return number_to_alpha($division, $code);   
    else
        $code .= $alphabets[$division];     

    return strrev($code);
}

将字母代码转换为数字

例如:bax 转 1402

function alpha_to_number($code)
{
    $alphabets = array('', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z');

    $sumval = 0;

    $code = strtolower(trim($code));

    $arr = str_split($code);
    $arr_length = count($arr);

    for($i = 0, $j = $arr_length-1; $i < $arr_length; $i++, $j--)
    {
        $arr_value = array_search($arr[$i], $alphabets);
        $sumval = $sumval + ($arr_value * pow(26, $j));
    }

    return $sumval;
}

to convert number to alphacode

for example: 1402 to bax

function number_to_alpha($num, $code)
{   
    $alphabets = array('', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z');

    $division = floor($num / 26);
    $remainder = $num % 26; 

    if($remainder == 0)
    {
        $division = $division - 1;
        $code .= 'z';
    }
    else
        $code .= $alphabets[$remainder];

    if($division > 26)
        return number_to_alpha($division, $code);   
    else
        $code .= $alphabets[$division];     

    return strrev($code);
}

to convert alphacode to number

for example: bax to 1402

function alpha_to_number($code)
{
    $alphabets = array('', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z');

    $sumval = 0;

    $code = strtolower(trim($code));

    $arr = str_split($code);
    $arr_length = count($arr);

    for($i = 0, $j = $arr_length-1; $i < $arr_length; $i++, $j--)
    {
        $arr_value = array_search($arr[$i], $alphabets);
        $sumval = $sumval + ($arr_value * pow(26, $j));
    }

    return $sumval;
}
一场信仰旅途 2024-12-15 04:07:17

我采用了“更正”的原始代码,删除了调试代码和其他不必要的代码,对其进行了修改,以便它可以处理任意数量的字符。例如,希腊语只有 24 个字符。

function toAlpha($number, $alphabet)
    {

        $count = count($alphabet);
        if ($number <= $count) {
            return $alphabet[$number - 1];
        }
        $alpha = '';
        while ($number > 0) {
            $modulo = ($number - 1) % $count;
            $alpha  = $alphabet[$modulo] . $alpha;
            $number = floor((($number - $modulo) / $count));
        }
        return $alpha;
    }

    toAlpha(45,range('a','z'));

以下是范围的一些示例:

// lower greek
$range = ['α', 'β', 'γ', 'δ', 'ε', 'ζ', 'η', 'θ', 'ι', 'κ', 'λ', 'μ', 'ν', 'ξ', 'ο', 'π', 'ρ', 'σ', 'τ', 'υ', 'φ', 'χ', 'ψ', 'ω'];
// upper greek 
$range = ['Α', 'Β', 'Γ', 'Δ', 'Ε', 'Ζ', 'Η', 'Θ', 'Ι', 'Κ', 'Λ', 'Μ', 'Ν', 'Ξ', 'Ο', 'Π', 'Ρ', 'Σ', 'Τ', 'Υ', 'Φ', 'Χ', 'Ψ', 'Ω'];
// georgian 
$range = ['ჵ' => 10000, 'ჰ' => 9000, 'ჯ' => 8000, 'ჴ' => 7000, 'ხ' => 6000, 'ჭ' => 5000, 'წ' => 4000, 'ძ' => 3000, 'ც' => 2000, 'ჩ' => 1000, 'შ' => 900, 'ყ' => 800, 'ღ' => 700, 'ქ' => 600, 'ფ' => 500, 'ჳ' => 400, 'ტ' => 300, 'ს' => 200, 'რ' => 100, 'ჟ' => 90, 'პ' => 80, 'ო' => 70, 'ჲ' => 60, 'ნ' => 50, 'მ' => 40, 'ლ' => 30, 'კ' => 20, 'ი' => 10, 'თ' => 9, 'ჱ' => 8, 'ზ' => 7, 'ვ' => 6, 'ე' => 5, 'დ' => 4, 'გ' => 3, 'ბ' => 2, 'ა' => 1];

I took the 'corrected' original, removed the debug code, and other unnecessary code, modified it so it will work with any number of characters. For example, Greek only has 24 characters.

function toAlpha($number, $alphabet)
    {

        $count = count($alphabet);
        if ($number <= $count) {
            return $alphabet[$number - 1];
        }
        $alpha = '';
        while ($number > 0) {
            $modulo = ($number - 1) % $count;
            $alpha  = $alphabet[$modulo] . $alpha;
            $number = floor((($number - $modulo) / $count));
        }
        return $alpha;
    }

    toAlpha(45,range('a','z'));

And here are some examples of ranges:

// lower greek
$range = ['α', 'β', 'γ', 'δ', 'ε', 'ζ', 'η', 'θ', 'ι', 'κ', 'λ', 'μ', 'ν', 'ξ', 'ο', 'π', 'ρ', 'σ', 'τ', 'υ', 'φ', 'χ', 'ψ', 'ω'];
// upper greek 
$range = ['Α', 'Β', 'Γ', 'Δ', 'Ε', 'Ζ', 'Η', 'Θ', 'Ι', 'Κ', 'Λ', 'Μ', 'Ν', 'Ξ', 'Ο', 'Π', 'Ρ', 'Σ', 'Τ', 'Υ', 'Φ', 'Χ', 'Ψ', 'Ω'];
// georgian 
$range = ['ჵ' => 10000, 'ჰ' => 9000, 'ჯ' => 8000, 'ჴ' => 7000, 'ხ' => 6000, 'ჭ' => 5000, 'წ' => 4000, 'ძ' => 3000, 'ც' => 2000, 'ჩ' => 1000, 'შ' => 900, 'ყ' => 800, 'ღ' => 700, 'ქ' => 600, 'ფ' => 500, 'ჳ' => 400, 'ტ' => 300, 'ს' => 200, 'რ' => 100, 'ჟ' => 90, 'პ' => 80, 'ო' => 70, 'ჲ' => 60, 'ნ' => 50, 'მ' => 40, 'ლ' => 30, 'კ' => 20, 'ი' => 10, 'თ' => 9, 'ჱ' => 8, 'ზ' => 7, 'ვ' => 6, 'ე' => 5, 'დ' => 4, 'გ' => 3, 'ბ' => 2, 'ა' => 1];
撩起发的微风 2024-12-15 04:07:17

这是一个可以使用非常高的列值(超过两个字母)的实现。电子表格将使用 01 作为第一个值,因此请务必将第二个参数 $indexStart 指定为 1(如果您使用的是 Excel);或者 0(默认值)(如果使用 Google Sheets)。

letterToColumnNumber()

/**
 * Converts a spreadsheet column letter (e.g., "A") to a column number (e.g., 1).
 * Can handle multi-letter columns, including Google's max column ZZZ (18277) 
 * and Excel's XFD (16384).
 * 
 * @param string $letters The column letters to convert.
 * @param int $indexStart Specifies if offsets begin with zero (Google Sheets) or one (Excel).
 * @return int The column number.
 */
function letterToColumnNumber(string $letters, int $indexStart = 0): int {
    $length = strlen($letters);
    $number = 0;
    $pow = 1;

    for ($i = $length - 1; $i >= 0; $i--) {
        // calculate the value of each letter and add to the total
        $number += (ord($letters[$i]) - ord('A') + 1) * $pow;
        $pow *= 26;
    }

    return $number - (1 - $indexStart);
}

echo letterToColumnNumber("ABC"); // returns 730
echo letterToColumnNumber("ABC", 1); // returns 731

此外,如果您希望将坐标引用(例如 A1:B2)转换为坐标数组(例如 [[0,0], [1,1]]),我们可以将此 letterToColumnNumber 函数与以下函数结合使用来实现:

rangeStringToRangeArray()

/**
 * Converts a spreadsheet range string like "A1:B2" into a coordinate array like [[0,0],[1,1]]
 * 
 * @param string $range The range string to convert.
 * @param int $indexStart Specifies if the index begins with zero (Google Sheets) or one (Excel).
 * @return array The coordinate array.
 */
function rangeStringToRangeArray(string $range, int $indexStart = 0): array {
    // Split the range into start and end parts
    [$startCell, $endCell] = explode(':', $range);

    // Separate letters and numbers for each part
    preg_match('/([A-Z]+)([0-9]+)/', $startCell, $startMatches);
    preg_match('/([A-Z]+)([0-9]+)/', $endCell, $endMatches);

    // Convert column letters to numbers
    $startColumn = letterToColumnNumber($startMatches[1], $indexStart);
    $endColumn = letterToColumnNumber($endMatches[1], $indexStart);

    // Convert row numbers
    $startRow = intval($startMatches[2]) - (1 - $indexStart); // Adjust for zero-based indexing
    $endRow = intval($endMatches[2]) - (1 - $indexStart);

    return [[$startColumn, $startRow], [$endColumn, $endRow]];
}

echo json_encode(rangeStringToRangeArray('A1:B2')); // returns [[0,0],[1,1]]
echo json_encode(rangeStringToRangeArray('A1:B2', 1)); // returns [[1,1],[2,2]]

如果您希望反转任一过程,以下两个函数结合在一起将实现该结果:

columnNumberToLetter()

/**
 * Converts a spreadsheet column number like 1 into a column letter reference like "A"
 * Can handle multi-letter columns including Google's max column 18277 (ZZZ) and 
 * Excel's 16384 (XFD).
 * 
 * @param int $columnNumber The column number to convert.
 * @param int $indexStart Specifies if the index begins with zero (Google Sheets) or one (Excel).
 * @return string The column letter.
 */
function columnNumberToLetter(int $columnNumber, int $indexStart = 0): string {
    $columnLetter = '';
    $columnNumber -= $indexStart;
    while ($columnNumber >= 0) {
        $modulus = $columnNumber % 26;
        $columnLetter = chr(65 + $modulus) . $columnLetter;
        $columnNumber = intdiv($columnNumber, 26) - 1;
    }
    return $columnLetter;
}

echo columnNumberToLetter(730); // returns "ABC"
echo columnNumberToLetter(731, 1); // returns "ABC"

rangeArrayToRangeString()

/**
 * Converts a spreadsheet coordinate array like [[0,0],[1,1]] into a range string like "A1:B2"
 * 
 * @param array $range The coordinate array to convert.
 * @param int $indexStart Specifies if the index begins with zero (Google Sheets) or one (Excel).
 * @return string The range string.
 */
function rangeArrayToRangeString(array $range, int $indexStart = 0): string {
    // Convert column numbers to letters
    $startColumn = columnNumberToLetter($range[0][0], $indexStart);
    $endColumn = columnNumberToLetter($range[1][0], $indexStart);

    // Convert row indices to spreadsheet row numbers
    $startRow = $range[0][1] + (1 - $indexStart);
    $endRow = $range[1][1] + (1 - $indexStart);

    // Combine to form range string
    return $startColumn . $startRow . ':' . $endColumn . $endRow;
}

echo rangeArrayToRangeString([[0,0],[1,1]]); // returns "A1:B2"
echo rangeArrayToRangeString([[1,1],[2,2]], 1); // returns "A1:B2"

当您与 Google Sheets API 集成时,此类代码非常有用。例如,如果您想获取所有冻结行和列的引用,这些行和列以整数而不是单元格引用的形式提供。

请注意,我在这些函数中包含了完全零错误检查,因此您会想要这样做。

Here is an implementation that can use very high column values (more than two letters). Spreadsheets will use either 0 or 1 as the first value, so be sure to specify the second parameter $indexStart as 1 if you are using Excel, or 0 (the default) if using Google Sheets.

letterToColumnNumber()

/**
 * Converts a spreadsheet column letter (e.g., "A") to a column number (e.g., 1).
 * Can handle multi-letter columns, including Google's max column ZZZ (18277) 
 * and Excel's XFD (16384).
 * 
 * @param string $letters The column letters to convert.
 * @param int $indexStart Specifies if offsets begin with zero (Google Sheets) or one (Excel).
 * @return int The column number.
 */
function letterToColumnNumber(string $letters, int $indexStart = 0): int {
    $length = strlen($letters);
    $number = 0;
    $pow = 1;

    for ($i = $length - 1; $i >= 0; $i--) {
        // calculate the value of each letter and add to the total
        $number += (ord($letters[$i]) - ord('A') + 1) * $pow;
        $pow *= 26;
    }

    return $number - (1 - $indexStart);
}

echo letterToColumnNumber("ABC"); // returns 730
echo letterToColumnNumber("ABC", 1); // returns 731

Additionally, if you wish to convert a coordinate reference (such as A1:B2) into a coordinate array (like [[0,0],[1,1]]), we can use this letterToColumnNumber function with the following function to achieve that:

rangeStringToRangeArray()

/**
 * Converts a spreadsheet range string like "A1:B2" into a coordinate array like [[0,0],[1,1]]
 * 
 * @param string $range The range string to convert.
 * @param int $indexStart Specifies if the index begins with zero (Google Sheets) or one (Excel).
 * @return array The coordinate array.
 */
function rangeStringToRangeArray(string $range, int $indexStart = 0): array {
    // Split the range into start and end parts
    [$startCell, $endCell] = explode(':', $range);

    // Separate letters and numbers for each part
    preg_match('/([A-Z]+)([0-9]+)/', $startCell, $startMatches);
    preg_match('/([A-Z]+)([0-9]+)/', $endCell, $endMatches);

    // Convert column letters to numbers
    $startColumn = letterToColumnNumber($startMatches[1], $indexStart);
    $endColumn = letterToColumnNumber($endMatches[1], $indexStart);

    // Convert row numbers
    $startRow = intval($startMatches[2]) - (1 - $indexStart); // Adjust for zero-based indexing
    $endRow = intval($endMatches[2]) - (1 - $indexStart);

    return [[$startColumn, $startRow], [$endColumn, $endRow]];
}

echo json_encode(rangeStringToRangeArray('A1:B2')); // returns [[0,0],[1,1]]
echo json_encode(rangeStringToRangeArray('A1:B2', 1)); // returns [[1,1],[2,2]]

If you wish to reverse either process, the following two functions together will achieve that result:

columnNumberToLetter()

/**
 * Converts a spreadsheet column number like 1 into a column letter reference like "A"
 * Can handle multi-letter columns including Google's max column 18277 (ZZZ) and 
 * Excel's 16384 (XFD).
 * 
 * @param int $columnNumber The column number to convert.
 * @param int $indexStart Specifies if the index begins with zero (Google Sheets) or one (Excel).
 * @return string The column letter.
 */
function columnNumberToLetter(int $columnNumber, int $indexStart = 0): string {
    $columnLetter = '';
    $columnNumber -= $indexStart;
    while ($columnNumber >= 0) {
        $modulus = $columnNumber % 26;
        $columnLetter = chr(65 + $modulus) . $columnLetter;
        $columnNumber = intdiv($columnNumber, 26) - 1;
    }
    return $columnLetter;
}

echo columnNumberToLetter(730); // returns "ABC"
echo columnNumberToLetter(731, 1); // returns "ABC"

rangeArrayToRangeString()

/**
 * Converts a spreadsheet coordinate array like [[0,0],[1,1]] into a range string like "A1:B2"
 * 
 * @param array $range The coordinate array to convert.
 * @param int $indexStart Specifies if the index begins with zero (Google Sheets) or one (Excel).
 * @return string The range string.
 */
function rangeArrayToRangeString(array $range, int $indexStart = 0): string {
    // Convert column numbers to letters
    $startColumn = columnNumberToLetter($range[0][0], $indexStart);
    $endColumn = columnNumberToLetter($range[1][0], $indexStart);

    // Convert row indices to spreadsheet row numbers
    $startRow = $range[0][1] + (1 - $indexStart);
    $endRow = $range[1][1] + (1 - $indexStart);

    // Combine to form range string
    return $startColumn . $startRow . ':' . $endColumn . $endRow;
}

echo rangeArrayToRangeString([[0,0],[1,1]]); // returns "A1:B2"
echo rangeArrayToRangeString([[1,1],[2,2]], 1); // returns "A1:B2"

This kind of code can be useful when you're integrating with Google Sheets API. E.g., if you want to get a reference for all the frozen rows and columns, which are provided as integers instead of a cell reference.

Please note that I have included exactly ZERO error checking in these functions, so you'll want to do that.

倾听心声的旋律 2024-12-15 04:07:17

这是对原始函数 toAlpha 的修复。它不适用于 toAlpha(27)

function toAlpha($n,$case = 'upper'){
    $alphabet   = array('A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z');
    $n = $n-1;
    Util::error_log('N'.$n);
    if($n <= 26){
        $alpha =  $alphabet[$n-1];
    } elseif($n > 26) {
        $dividend   = ($n);
        $alpha      = '';
        $modulo;
        while($dividend > 0){
            $modulo     = ($dividend - 1) % 26;
            $alpha      = $alphabet[$modulo].$alpha;
            $dividend   = floor((($dividend - $modulo) / 26));
        }
    }

    if($case=='lower'){
        $alpha = strtolower($alpha);
    }
    Util::error_log("**************".$alpha);
    return $alpha;

}

Here is a fix to original function toAlpha. It is not working for toAlpha(27)

function toAlpha($n,$case = 'upper'){
    $alphabet   = array('A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z');
    $n = $n-1;
    Util::error_log('N'.$n);
    if($n <= 26){
        $alpha =  $alphabet[$n-1];
    } elseif($n > 26) {
        $dividend   = ($n);
        $alpha      = '';
        $modulo;
        while($dividend > 0){
            $modulo     = ($dividend - 1) % 26;
            $alpha      = $alphabet[$modulo].$alpha;
            $dividend   = floor((($dividend - $modulo) / 26));
        }
    }

    if($case=='lower'){
        $alpha = strtolower($alpha);
    }
    Util::error_log("**************".$alpha);
    return $alpha;

}
鲸落 2024-12-15 04:07:17

我这样做是为了在 int 参数之前使用修复字符长度
A = 0 ,Z = 25

function returnUIDfixChar(int $inc,int $charlength=3,int $min_input_length=3,string $prefix=''):string {
$alpha = range('A','Z');
$max_alpa_int = count($alpha)-1;
$over = 0;
$output_prefix = '';
$first_split = 0;
if(strlen($inc)>$min_input_length)
{
    $first_split = substr((string) $inc,0,strlen($inc)-$min_input_length);
}
$second_split = substr((string) $inc,0,$min_input_length);
for($i=0;$i<$charlength;$i++)
{
    $temp_over = (float) $first_split - $max_alpa_int;
    if($temp_over>0)
    {
        $output_prefix = $alpha[$max_alpa_int].$output_prefix;
        $first_split -= $max_alpa_int;
    }
    elseif($first_split<$max_alpa_int && $first_split>0)
    {
        $output_prefix = $alpha[$first_split].$output_prefix;
        $first_split -= $first_split;
    }
    else
    {
        $output_prefix = $alpha[0].$output_prefix;
    }
    $over = $first_split;
}
if(strlen($second_split)<$min_input_length)
{
    for($i=0;$i<$min_input_length-strlen($second_split);$i++)
    {
        $second_split = '0'.$second_split;
    }
}
return $output_prefix.($first_split>0?$first_split:'').$second_split;

}

i do this stuff to use fix char lenght before int parameter
A = 0 ,Z = 25

function returnUIDfixChar(int $inc,int $charlength=3,int $min_input_length=3,string $prefix=''):string {
$alpha = range('A','Z');
$max_alpa_int = count($alpha)-1;
$over = 0;
$output_prefix = '';
$first_split = 0;
if(strlen($inc)>$min_input_length)
{
    $first_split = substr((string) $inc,0,strlen($inc)-$min_input_length);
}
$second_split = substr((string) $inc,0,$min_input_length);
for($i=0;$i<$charlength;$i++)
{
    $temp_over = (float) $first_split - $max_alpa_int;
    if($temp_over>0)
    {
        $output_prefix = $alpha[$max_alpa_int].$output_prefix;
        $first_split -= $max_alpa_int;
    }
    elseif($first_split<$max_alpa_int && $first_split>0)
    {
        $output_prefix = $alpha[$first_split].$output_prefix;
        $first_split -= $first_split;
    }
    else
    {
        $output_prefix = $alpha[0].$output_prefix;
    }
    $over = $first_split;
}
if(strlen($second_split)<$min_input_length)
{
    for($i=0;$i<$min_input_length-strlen($second_split);$i++)
    {
        $second_split = '0'.$second_split;
    }
}
return $output_prefix.($first_split>0?$first_split:'').$second_split;

}

节枝 2024-12-15 04:07:17

如果数字从 1 开始:

function num2alpha($n) {
    $r = '';
    while( $n > 0 ) {
        $r = chr( ($n-1) % 26 + 0x41 ) . $r;
        $n = floor( ($n-1) / 26 );
    }
    return $r;
}

If the numbers start at 1:

function num2alpha($n) {
    $r = '';
    while( $n > 0 ) {
        $r = chr( ($n-1) % 26 + 0x41 ) . $r;
        $n = floor( ($n-1) / 26 );
    }
    return $r;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文