如何在PHP中像增加数字一样增加字母?

rpppsulh  于 2023-04-04  发布在  PHP
关注(0)|答案(8)|浏览(110)

我想写一个函数,它接受3个字符并递增它,并将新增加的字符作为字符串返回。
我知道如何增加一个字母到下一个,但我怎么知道什么时候增加第二个字母,然后停止,然后再次增加第一个字母,以获得连续的增加?
所以如果AAA通过,返回AAB。如果AAZ通过,返回阿坝(硬部分)。
我将感谢帮助的逻辑和什么php函数将是有用的使用。
更好的是,有没有一些已经这样做了,或者有一个类可以这样做??
谢谢大家的帮助

wlp8pajw

wlp8pajw1#

字符/字符串增量在PHP中可以工作(尽管减量不能)

$x = 'AAZ';
$x++;
echo $x;  // 'ABA'
fnvucqvd

fnvucqvd2#

你可以用++操作符来实现。

$i = 'aaz';
$i++;
print $i;

阿坝
然而,这个实现有一些奇怪的事情:

for($i = 'a'; $i < 'z'; $i++) print "$i ";

这将打印出从ay的字母。

for($i = 'a'; $i <= 'z'; $i++) print "$i ";

这将打印出从az的字母,并以aa继续,以yz结束。

pes8fvy9

pes8fvy93#

PHP RFC: Strict operators directive(* 目前正在讨论中 *)所述:
当strict_operators启用时,对字符串使用increment函数将抛出TypeError。
不管RFC是否被合并,PHP迟早会加入严格的运算符。因此,你不应该递增字符串

a-z/A-Z范围

如果你知道你的字母将保持在a-z/A-Z范围内(不超过z/Z),你可以使用将字母转换为ASCII代码的解决方案,递增它,然后转换回字母。
使用ord() a chr()

$letter = 'A';
$letterAscii = ord($letter);
$letterAscii++;
$letter = chr($letterAscii); // 'B'
  1. ord()将字母转换为ASCII数字表示
    1.递增该数字表示
    1.使用chr()将数字转换回字母
  • 正如在注解中发现的,要小心。这会迭代ASCII表,因此从Z(ASCII 90)开始,它不会转到AA,而是[(ASCII 91)。*

超越z/Z

如果你还想把z变成aa,这就是我的想法:

final class NextLetter
{
    private const ASCII_UPPER_CASE_BOUNDARIES = [65, 91];
    private const ASCII_LOWER_CASE_BOUNDARIES = [97, 123];

    public static function get(string $previous) : string
    {
        $letters = str_split($previous);
        $output = '';
        $increase = true;

        while (! empty($letters)) {
            $letter = array_pop($letters);

            if ($increase) {
                $letterAscii = ord($letter);
                $letterAscii++;
                if ($letterAscii === self::ASCII_UPPER_CASE_BOUNDARIES[1]) {
                    $letterAscii = self::ASCII_UPPER_CASE_BOUNDARIES[0];
                    $increase = true;
                } elseif ($letterAscii === self::ASCII_LOWER_CASE_BOUNDARIES[1]) {
                    $letterAscii = self::ASCII_LOWER_CASE_BOUNDARIES[0];
                    $increase = true;
                } else {
                    $increase = false;
                }

                $letter = chr($letterAscii);
                if ($increase && empty($letters)) {
                    $letter .= $letter;
                }
            }

            $output = $letter . $output;
        }

        return $output;
    }
}

如果你打算进一步使用它,我也给你100%的覆盖率。它测试原始字符串增量++

/**
     * @dataProvider letterProvider
     */
    public function testIncrementLetter(string $givenLetter) : void
    {
        $expectedValue = $givenLetter;

        self::assertSame(++$expectedValue, NextLetter::get($givenLetter));
    }

    /** 
     * @return iterable<array-key, array<string>>
     */
    public static function letterProvider() : iterable
    {
        yield ['A'];
        yield ['a'];
        yield ['z'];
        yield ['Z'];
        yield ['aaz'];
        yield ['aaZ'];
        yield ['abz'];
        yield ['abZ'];
    }
ni65a41a

ni65a41a4#

在7位128个字符的ASCII范围内递增或递减**,最安全的方法是:

$CHAR = "l";
echo chr(ord($CHAR)+1)." ".chr(ord($CHAR)-1);
/* m k */

因此,通过递减a来获得反勾是正常的,因为ascii spec list
打印整个ascii范围:

for ($i = 0;$i < 127;$i++){
    echo chr($i);
}
/* !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ */

关于ANSI7 bits ASCII的更多信息:man ascii
8位扩展的256个字符UTF-8范围内递增或递减
这就是它在主机字符集方面开始不同的地方。但是这些字符集在现代机器上都是可用的。从php开始,最安全的是使用php-mbstring扩展:https://www.php.net/manual/en/function.mb-chr.php
扩展ASCII(EASCII或高ASCII)字符编码是8位或更大的编码,包括标准的7位ASCII字符以及其他字符。https://en.wikipedia.org/wiki/Extended_ASCII
更多信息,例如:man iso_8859-9

ISO 8859-1    West European languages (Latin-1)
   ISO 8859-2    Central and East European languages (Latin-2)
   ISO 8859-3    Southeast European and miscellaneous languages (Latin-3)
   ISO 8859-4    Scandinavian/Baltic languages (Latin-4)
   ISO 8859-5    Latin/Cyrillic
   ISO 8859-6    Latin/Arabic
   ISO 8859-7    Latin/Greek
   ISO 8859-8    Latin/Hebrew
   ISO 8859-9    Latin-1 modification for Turkish (Latin-5)
   ISO 8859-10   Lappish/Nordic/Eskimo languages (Latin-6)
   ISO 8859-11   Latin/Thai
   ISO 8859-13   Baltic Rim languages (Latin-7)
   ISO 8859-14   Celtic (Latin-8)
   ISO 8859-15   West European languages (Latin-9)
   ISO 8859-16   Romanian (Latin-10)

例如,我们可以在ISO 8859-7中找到符号:

244   164   A4     €     EURO SIGN

在16位UTF-16 Unicode范围内递增或递减**:
下面是生成整个unicode字符集的方法,通过生成html实体并转换为utf8.Run it online

for ($x = 0; $x < 262144; $x++){
  echo html_entity_decode("&#".$x.";",ENT_NOQUOTES,"UTF-8");
}

同样的东西,但范围上升到(16^4 * 4)

echo html_entity_decode('&#33;',ENT_NOQUOTES,'UTF-8');
/* ! */
echo html_entity_decode('&#34;',ENT_NOQUOTES,'UTF-8');
/* " */

使用字符的 * base 10 * 十进制表示来检索the unicode symbol

echo html_entity_decode('&#8364;',ENT_NOQUOTES,'UTF-8');
/* € */

相同的符号,使用 * base 16 * 十六进制表示:

echo html_entity_decode('&#'.hexdec("20AC").';',ENT_NOQUOTES,'UTF-8');
/* € */

前32位是为special control characters保留的,输出垃圾,但有意义。

1aaf6o9v

1aaf6o9v5#

你正在看一个数字表示问题。这是base24(或者你的字母表中有多少数字)。让我们称之为基数b。
给字母表中的每个字母分配一个数字(A=1,B=2,C=3)。
接下来,计算出你输入的“数字”:表示法“ABC”的意思是A*b^2 + B*b^1 + C*b^0使用这个公式来找到数字(int)。递增它。
接下来,将其转换回您的数字系统:除以b^2得到第三位数,余数(模)除以b^1得到第二位数,余数(模)除以`b^0^得到最后一位数。
这可能有助于:How to convert from base10 to any other base .

xtupzzrd

xtupzzrd6#

你可以用ASCII码来表示字母数字,从那里你可以递增和递减来得到上一个/下一个字符。
您可以将字符串拆分为单个字符,然后对这些字符应用转换。
只是一些想法让你开始。

nzk0hqpo

nzk0hqpo7#

<?php 
$values[] = 'B';
$values[] = 'A';
$values[] = 'Z';
foreach($values as $value ){
  if($value == 'Z'){ 
       $value = '-1';
    }
$op = ++$value;
echo $op;
}
?>
wwwo4jvm

wwwo4jvm8#

我在c#中有这些方法,你可以转换为php并修改以满足你的需要,我不确定Hexavigesimal是这些方法的确切名称。

#region Hexavigesimal (Excel Column Name to Number)
public static int FromHexavigesimal(this string s)
{
    int i = 0;
    s = s.Reverse();
    for (int p = s.Length - 1; p >= 0; p--)
    {
        char c = s[p];
        i += c.toInt() * (int)Math.Pow(26, p);
    }

    return i;
}

public static string ToHexavigesimal(this int i)
{
    StringBuilder s = new StringBuilder();

    while (i > 26)
    {
        int r = i % 26;
        if (r == 0)
        {
            i -= 26;
            s.Insert(0, 'Z');
        }
        else
        {
            s.Insert(0, r.toChar());
        }

        i = i / 26;
    }

    return s.Insert(0, i.toChar()).ToString();
}

public static string Increment(this string s, int offset)
{
    return (s.FromHexavigesimal() + offset).ToHexavigesimal();
}

private static char toChar(this int i)
{
    return (char)(i + 64);
}

private static int toInt(this char c)
{
    return (int)c - 64;
}
#endregion

编辑

我看到其他的答案,在PHP中你可以使用++代替,很好!

相关问题