PHP中的range()函数如何从A到ZZ?

35

能否用PHP得到从A到ZZ*的范围?

a b c ... aa ... zx zy zz

对我来说,这个方法不起作用:

range('A', 'ZZ');

这是关于PHPExcel的问题,当最高字段为BE时,我会遍历所有列。在这种情况下,我只得到A、B两列:

range ('A', 'BE')

https://phpspreadsheet.readthedocs.io/en/latest/ - CrandellWS
18个回答

69

利用PHP递增字符“Perl风格”的能力

$letters = array();
$letter = 'A';
while ($letter !== 'AAA') {
    $letters[] = $letter++;
}

但你也可以使用简单的整数值,并利用PHPExcel内置的PHPExcel_Cell ::stringFromColumnIndex()方法。

编辑

从PHP 5.5开始,您还可以使用生成器来避免实际在内存中构建数组。

function excelColumnRange($lower, $upper) {
    ++$upper;
    for ($i = $lower; $i !== $upper; ++$i) {
        yield $i;
    }
}

foreach (excelColumnRange('A', 'ZZ') as $value) {
    echo $value, PHP_EOL;
}

1
循环的结束条件的主要问题是“不要使用>或<”,始终使用!==; 但这是一个非常有用的功能。不幸的是,您不能使用--递减器。 - Mark Baker
@MarkBaker 你知道我们为什么不能使用递减操作符吗?还有为什么“不要在循环中使用 > 或 < ”? - Viacheslav Kondratiuk
这似乎不再起作用了 - 至少在我的php 5.5上是这样。 - Jacob Thomason
这段代码在 PHP >= 5.5 中仍然以完全相同的方式工作,尽管您也可以利用 PHP 5.5 中的新功能,例如生成器。 - Mark Baker
https://phpspreadsheet.readthedocs.io/en/latest/ - CrandellWS
显示剩余3条评论

18

请尝试这个(已测试,正常工作)

function createColumnsArray($end_column, $first_letters = '')
{
  $columns = array();
  $length = strlen($end_column);
  $letters = range('A', 'Z');

  // Iterate over 26 letters.
  foreach ($letters as $letter) {
      // Paste the $first_letters before the next.
      $column = $first_letters . $letter;

      // Add the column to the final array.
      $columns[] = $column;

      // If it was the end column that was added, return the columns.
      if ($column == $end_column)
          return $columns;
  }

  // Add the column children.
  foreach ($columns as $column) {
      // Don't itterate if the $end_column was already set in a previous itteration.
      // Stop iterating if you've reached the maximum character length.
      if (!in_array($end_column, $columns) && strlen($column) < $length) {
          $new_columns = createColumnsArray($end_column, $column);
          // Merge the new columns which were created with the final columns array.
          $columns = array_merge($columns, $new_columns);
      }
  }

  return $columns;
}
echo "<pre>";
print_r( createColumnsArray('BZ'));

copied from http://php.net/range


16
for ($i = 'A'; $i !== 'AC'; $i++){
    echo $i.', '; //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, AA, AB,
}

它正在工作


8
您可以组合两个foreach循环来生成类似的内容。
// Single letters
foreach(range('A', 'Z') as $letter) {
    echo $letter;
}

// AA-ZZ combinations
foreach(range('A', 'Z') as $letter1) {
    foreach(range('A', 'Z') as $letter2) {
        echo $letter1 . $letter2;
    }
}

2
使用内置的 range 函数是不可能的:

从 4.1.0 开始,添加了对字符序列和递减数组的支持。字符序列值限制为长度为一。如果输入大于一的长度,则仅使用第一个字符。

然而,本质上你正在使用一个数字系统从 1 开始向上计数,该数字系统使用 26 个字母 a 到 z。因此,你可以通过计数、转换为基数 26(使用数字 0 到 9 和字母 a 到 p)然后将数字“翻译”为范围 a 到 z 来快速拼凑出一个解决方案。

2
更好的选择(运作良好)
for ($i = 'a'; $i < 'zz'; $i++) 
    echo $i."<br>";

1
它不会给出 OP 提到的 'zz' 结尾值,你该如何修改才能得到它? - Mark Baker
2
使用 < 或 > 是危险的。 - Mark Baker

1

当然,你可以编写自己的函数来实现这个功能,因为似乎php中的range()函数不支持此操作。这应该是一个很容易的任务,因为你只需要将range函数嵌套在另一个循环中即可。类似于这样:

foreach(range('a', 'z') as $outer) {
  foreach(range('a', 'z') as $inner) {
    print($outer.$inner);
  }
}

1
请检查这个简单的解决方案,它可以递增字符。
使用这个递归函数来获取从A到ZZ的精确范围。 如何在PHP中按字母顺序列出A到Z,然后是AA、AB、AC等
function myRange($end_column = '', $first_letters = '') {
    $columns = array();
    $length = strlen($end_column);
    $letters = range('A', 'Z');

    // Iterate over 26 letters.
    foreach ($letters as $letter) {
      // Paste the $first_letters before the next.
      $column = $first_letters . $letter; 
      // Add the column to the final array.
      $columns[] = $column;
      // If it was the end column that was added, return the columns.
      if ($column == $end_column)
          return $columns;
    }

    // Add the column children.
    foreach ($columns as $column) {
      // Don't itterate if the $end_column was already set in a previous itteration.
      // Stop iterating if you've reached the maximum character length.
      if (!in_array($end_column, $columns) && strlen($column) < $length) {
          $new_columns = myRange($end_column, $column);
          // Merge the new columns which were created with the final columns array.
          $columns = array_merge($columns, $new_columns);
      }
    }

    return $columns;
}

调用函数的方式如下。
print_r(myRange('ZZ'));

将会给你结果

A B C . . . ZX ZY ZZ


0
这里有一个简化的解决方案,你可以定义要生成的行数和列数。这样你就可以分配较少的内存。
// Get cell names for excel
function generate_excel_cell_names($row_cnt, $col_cnt){
    $excel_cells = [];

    // Note: Row and col indexes are starting from 1
    for ($excel_row=1; $excel_row <= $row_cnt; $excel_row++) { 
        $excel_col = 'A';
        for ($col_index = 1; $col_index <= $col_cnt; $col_index++)
        {
            $excel_cells[$excel_row][$col_index] = $excel_col.$excel_row;
            $excel_col++;
        }
    }
    return $excel_cells;
}

0

如果你不知道要获取哪个字母,但是你知道它的长度:

$max = 200; 
for ($l = 'A', $i = 0; $i < $max; $l++, $i++) {
    $letters[] = $l;
}
echo $letters; 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接