将Excel列坐标转换为PHP中的整数位置

我需要将Excel坐标(例如“AD45”)转换为X = 30和Y = 45的整数位置。

我有这个PHP代码片段:

/** * @param String $coordinates * * @return array */ public function getCoordinatesPositions($coordinates) { $letters = preg_replace('/[^a-zA-Z]/', '', $coordinates); $numbers = preg_replace('/[^0-9]/', '', $coordinates); $letters = strtoupper($letters); $columnCoordinate = 0; $alphabetIterate = 0; $alphabetRange = range('A', 'Z'); $alphabetCount = count($alphabetRange); $splittedLetters = str_split($letters); $lettersCount = count($splittedLetters); $i = 1; if ($lettersCount === 1) { $columnCoordinate = array_search($splittedLetters[0], $alphabetRange) + 1; } else { foreach ($splittedLetters as $letter) { if ($i !== $lettersCount) { $position = (array_search($letter, $alphabetRange) + 1) * $alphabetCount; } else { $position = (array_search($letter, $alphabetRange) + 1); } $columnCoordinate += $position; $i++; } } return array('column' => $columnCoordinate, 'row' => $numbers); } 

我的问题是,如果您传递带有3个或更多字母的坐标(“ABC45”),则此函数不会返回正确的列值。 而我的同事说,这个algorithm性能也不好。

你有更简单和更好的性能algorithm的任何想法? 谢谢。

@Axel Richter的答案是一个很好的解决scheme,并且可以正常工作,但可能会改进为:

  • 防止错误的坐标。
  • 减less代码。
  • 而且可能会提高性能。

这是build议的版本:

 function getCoordinatesPositions($coordinates) { if (preg_match('/^([az]+)(\d+)$/i', $coordinates, $matches)) { $level = strlen($matches[1]); $matches[1] = array_reduce( str_split(strtoupper($matches[1])), function($result, $letter) use (&$level) { return $result + (ord($letter) - 64) * pow(26, --$level); } ); return array_splice($matches, 1); } // (returns NULL when wrong $coordinates) } 

使用初始的preg_match()确保避免使用错误的坐标,直接将列部分提取到$matches['1']

现在主要的改进是使用ord($letter)来计算字母的单个值:它避免了创build一个range('A', 'Z')的临时数组range('A', 'Z') ,并简化了评估。

然后, array_reduce()允许对array_reduce()部分的列部分进行更紧凑的处理,所以最终的返回也简化为中间$matches一个简单部分。

原则上algorithm是好的。 你可以简化它,并使其更通用:

 function getCoordinatesPositions($coordinates) { $letters = preg_replace('/[^a-zA-Z]/', '', $coordinates); $numbers = preg_replace('/[^0-9]/', '', $coordinates); $letters = strtoupper($letters); $alphabetRange = range('A', 'Z'); $alphabetCount = count($alphabetRange); $splittedLetters = str_split($letters); $lettersCount = count($splittedLetters); $columnCoordinate = 0; $i = 1; foreach ($splittedLetters as $letter) { $columnCoordinate += (array_search($letter, $alphabetRange) + 1) * pow($alphabetCount, $lettersCount - $i); $i++; } return array('column' => $columnCoordinate, 'row' => intval($numbers)); } var_dump(getCoordinatesPositions("ABC456")); 

对于PHPExcel请参阅PHPExcel如何从单元格获取列索引 。