php 如何在PHP中增加数字之类的字母?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3567180/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 10:15:33  来源:igfitidea点击:

How to increment letters like numbers in PHP?

php

提问by Abs

I would like to write a function that takes in 3 characters and increments it and returns the newly incremented characters as a string.

我想编写一个函数,它接受 3 个字符并递增它并将新递增的字符作为字符串返回。

I know how to increase a single letter to the next one but how would I know when to increase the second letters and then stop and then increase the first letter again to have a sequential increase?

我知道如何将单个字母增加到下一个字母,但我怎么知道何时增加第二个字母然后停止然后再次增加第一个字母以进行顺序增加?

So if AAA is passed, return AAB. If AAZ is passed return ABA (hard part).

所以如果AAA通过,返回AAB。如果通过了 AAZ,则返回 ABA(难点)。

I would appreciate help with the logic and what php functions will be useful to use.

我很感激逻辑方面的帮助以及使用哪些 php 函数会很有用。

Even better, has some done this already or there is a class available to do this??

更好的是,有人已经这样做了,或者有一个课程可以做到这一点?

Thanks all for any help

感谢大家的帮助

回答by Mark Baker

Character/string increment works in PHP (though decrement doesn't)

字符/字符串增量在 PHP 中有效(尽管减量不起作用)

$x = 'AAZ';
$x++;
echo $x;

回答by tamasd

You can do it with the ++ operator.

您可以使用 ++ 运算符来完成。

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

aba

阿坝

However this implementation has some strange things:

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

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

This will print out letters from ato y.

这将打印出从a到的字母y

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

This will print out lettes from ato zand it continues with aaand ends with yz.

这将从ato打印出字母zaa并以yz.

回答by simPod

As proposed in PHP RFC: Strict operators directive (currently Under Discussion):

正如PHP RFC: Strict operators 指令中 所提议的(目前正在讨论中):

Using the increment function on a string will throw a TypeError when strict_operators is enabled.

启用strict_operators 时,在字符串上使用增量函数将引发TypeError。

Whether or not the RFC gets merged, PHP will sooner or later go that direction of adding operator strictness. Therefore, you should not be incrementing strings.

无论 RFC 是否合并,PHP 迟早都会朝着添加运算符严格性的方向发展。因此,您不应该增加 strings

a-z/A-Z ranges

z/AZ 范围

If you know your letters will stay in range a-z/A-Z (not surpass z/Z), you can use the solution that converts letter to ASCII code, increments it, and converts back to letter.

如果您知道您的字母将保持在 z/AZ 范围内(不超过 z/Z),您可以使用将字母转换为 ASCII 代码、递增并转换回字母的解决方案。

Use ord()a chr():

使用ord()一个chr()

$letter = 'A';
$letterAscii = ord($letter);
$letterAscii++;
$letter = chr($letterAscii); // 'B'
  1. ord()converts the letter into ASCII num representation
  2. that num representation is incremented
  3. using chr()the number gets converted back to the letter
  1. ord()将字母转换为 ASCII num 表示
  2. 该 num 表示增加
  3. 使用chr()数字被转换回字母

As discovered in comments, be careful. This iterates ASCII table so from Z(ASCII 90), it does not go to AA, but to [(ASCII 91).

正如在评论中发现的那样,要小心。这将迭代 ASCII 表,因此从Z(ASCII 90) 开始,它不会转到AA,而是转到[(ASCII 91)。

Going beyond z/Z

超越 z/Z

If you dare to go further and want zbecame aa, this is what I came up with:

如果你敢更进一步,想要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;
    }
}

I'm giving you also 100% coverage if you intend to work with it further. It tests against original string incrementation ++:

如果您打算进一步使用它,我也会为您提供 100% 的覆盖率。它针对原始字符串增量进行测试++

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

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

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

回答by NVRM

To increment or decrement in the 7bits 128 chars ASCII range, the safest:

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

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

So, it is normal to get a backtick by decrementing a, as the ascii spec list

因此,通过递减来获得反引号是正常的a,如ascii 规范列表

Print the whole asciirange:

打印整个ascii范围:

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

More infos about ANSI7 bits ASCII: man ascii

有关ANSI 7 位 ASCII 的更多信息:man ascii



To increment or decrement in the 8-bits extended 256 chars UTF-8 range.

8 位扩展 256 个字符的 UTF-8 范围内递增或递减。

This is where it starts to differ regarding the host machine charset. but those charsets are all available on modern machines. From php, the safest is to use the php-mbstringextension: https://www.php.net/manual/en/function.mb-chr.php

这是主机字符集开始不同的地方。但是这些字符集都可以在现代机器上使用。从php,最安全的是使用php-mbstring扩展名:https: //www.php.net/manual/en/function.mb-chr.php

Extended ASCII (EASCII or high ASCII) character encodings are eight-bit or larger encodings that include the standard seven-bit ASCII characters, plus additional characters. https://en.wikipedia.org/wiki/Extended_ASCII

扩展 ASCII(EASCII 或高位 ASCII)字符编码是八位或更大的编码,包括标准的七位 ASCII 字符和附加字符。https://en.wikipedia.org/wiki/Extended_ASCII

More info, as example: man iso_8859-9

更多信息,例如: 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)

Example, we can find the symbol in ISO 8859-7:

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

244   164   A4          EURO SIGN


To increment or decrement in the 16 bits UTF-16 Unicode range:

在 16 位 UTF-16 Unicode 范围内递增或递减:

Here is a way to generate the whole unicode charset, by generating html entities and converting to utf8. Run it online

这是一种生成整个 unicode 字符集的方法,通过生成 html 实体并转换为 utf8。在线运行

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

Same stuff, but the range goes up to (16^4 * 4)!

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

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

To retrieve the unicode symbol,using the base10decimal representation of the character.

要检索unicode符号,请使用字符的base10十进制表示。

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

The same symbol, using the base16hexadecimal representation:

相同的符号,使用base16十六进制表示:

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

First 32 bits are reserved for special control characters, output garbage ?????, but have a meaning.

前32位是为特殊控制字符保留的,输出垃圾?????,但有一个含义。

回答by Daren Thomas

You are looking at a number representation problem. This is base24 (or however many numbers your alphabet has). Lets call the base b.

您正在查看数字表示问题。这是 base24(或者你的字母表有多少个数字)。让我们称之为基地 b。

Assign a number to each letter in alphabet (A=1, B=2, C=3).

为字母表中的每个字母指定一个数字(A=1、B=2、C=3)。

Next, figure out your input "number": The representation "ABC" means A*b^2 + B*b^1 + C*b^0Use this formula to find the number (int). Increment it.

接下来,找出您输入的“数字”:表示“ABC”的意思是A*b^2 + B*b^1 + C*b^0使用此公式来查找数字 (int)。增加它。

Next, convert it back to your number system: Divide by b^2to get third digit, the remainder (modulo) by b^1for second digit, the remainder (modulo) by `b^0^ for last digit.

接下来,将其转换回您的数字系统:除以b^2得到第三位数字,余数(模数)b^1为第二位数字,余数(模数)为最后一位数的`b^0^。

This might help: How to convert from base10 to any other base.

这可能会有所帮助:How to convert from base10 to any other base

回答by Andreas

You could use the ASCII codes for alpha numerics. From there you increment and decrement to get the previous/next character.

您可以将 ASCII 代码用于字母数字。从那里你增加和减少以获得上一个/下一个字符。

You could split your string in single characters and then apply the transformations on these characters.

您可以将字符串拆分为单个字符,然后对这些字符应用转换。

Just some thoughts to get you started.

只是一些让你开始的想法。

回答by Vimal Kumar E

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

回答by CaffGeek

I have these methods in c# that you could probably convert to php and modify to suit your needs, I'm not sure Hexavigesimal is the exact name for these though...

我在 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

EDIT

编辑

I see by the other answers that in PHP you can use ++instead, nice!

我从其他答案中看到,您可以在 PHP 中使用++,很好!