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

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

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

So if AAA is passed, return AAB. If

AAZ is passed return ABA (hard part).

我希望您能提供有关逻辑的帮助以及使用哪些PHP函数的帮助。

更好的是,是否已经完成了此操作,或者有可用的类来执行此操作?

谢谢大家的帮助

我不明白。 AAA => AAB,但AAZ => ABA。 您如何确定要递增的字母? 您说增加第二个字母,所以我认为您是指除第一个字母以外的所有字母? 如果您将除第一个字母以外的所有字母加一,是否应该是AAA => ABB?

@Raoul Duke:以26为基数,没有数字,只有字母。

@Matt啊,好吧。 谢谢

@Raoul-只需运行$ X = AAA; for($ i = 1; $ i <1024; $ i ++){echo $ X ++,

; }看看是什么意思。

字符/字符串递增在PHP中有效(尽管不能递减)

$x = 'AAZ';

$x++;

echo $x;

遗憾的是$ x--无法正常工作。 @wimvds-感谢您添加链接

或者只是echo ++$x; :)

正如文档所述,decementing应该与$ a--一起使用:php.net/manual/en/language.operators.increment.php

@TobiasGaertner-递减数字适用于$a--;减少字符/字母不会...示例...并且您链接的文档页面专门显示Note that character variables can be incremented but not decremented

@Mark Ba??ker-是的,您是对的-我的错误-只是写得不够仔细。抱歉

您可以使用++运算符。

$i = 'aaz';

$i++;

print $i;

aba

但是,此实现有一些奇怪的事情:

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

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

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

这将打印出从a到z的字母,并以aa继续,以yz结尾。

它并不奇怪,只是不直观。如果$i == z条件仍然成立,并且for循环将继续,将$i设置为aa。仅当$i达到za时,条件才变为假。

如PHP RFC中所建议:严格运算符指令

(目前正在讨论中):

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

无论RFC是否合并,PHP迟早都会朝着增加操作员严格性的方向发展。因此,不应增加字符串。

a-z / A-Z范围

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

使用ord()和chr():

$letter = 'A';

$letterAscii = ord($letter);

$letterAscii++;

$letter = chr($letterAscii); // 'B'

ord()将字母转换为ASCII num表示形式

num表示递增

使用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

*/

public function letterProvider() : iterable

{

yield ['A'];

yield ['a'];

yield ['z'];

yield ['Z'];

yield ['aaz'];

yield ['aaZ'];

yield ['abz'];

yield ['abZ'];

}

香港专业教育学院尝试过,但它不是从z到aa,而是到{,不是什么奇怪的字符。

嗯,好点,我从来没有走过这么远。我已经编辑了答案。提供反馈对其他人也有帮助,谢谢;)我将尝试编写有效的解决方案而不增加字符串并将其发布在此处。

@ArendE Ive进一步更新了答案

哇,超越! ??

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

$CHAR ="l";

echo chr(ord($CHAR)+1)."".chr(ord($CHAR)-1);

/* m k */

因此,通过递减a作为ascii规范列表来反击是很正常的

打印整个ASCII范围:

for ($i = 0;$i < 127;$i++){

echo chr($i);

}

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

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

在8位中增加或减少256个字符的UTF-8范围。

这在主机字符集方面开始有所不同。但是这些字符集都可以在现代机器上使用。在php中,最安全的方法是使用php-mbstring扩展名:https://www.php.net/manual/zh/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

例如,更多信息: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范围内递增或递减:

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

for ($x = 0; $x < 262144; $x++){

echo html_entity_decode("".$x.";",ENT_NOQUOTES,"UTF-8");

}

相同的东西,但范围高达(16^4 * 4)!

echo html_entity_decode('',ENT_NOQUOTES,'UTF-8');

/* ! */

echo html_entity_decode('',ENT_NOQUOTES,'UTF-8');

/*" */

要检索Unicode €符号,请使用该字符的base10小数表示。

echo html_entity_decode('€',ENT_NOQUOTES,'UTF-8');

/* € */

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

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

/* € */

前32位保留用于特殊控制字符,输出垃圾?????,但有含义。

您正在查看数字表示法问题。这是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 ^除以余数。

这可能会有所帮助:如何从base10转换为任何其他基准。

对。我永远无法真正记住字母表中有多少个字母。这也取决于您的计算方式(有些人忽略了" j"和" v"只是给我的一封不真实的信...

$values[] = 'B';

$values[] = 'A';

$values[] = 'Z';

foreach($values as $value ){

if($value == 'Z'){

$value = '-1';

}

$op = ++$value;

echo $op;

}

?>

至少有一点解释必将对OP和您的答案提供进一步的帮助

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

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

只是一些想法可以帮助您入门。

我在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中可以使用++代替,太好了!

该代码不必要地复杂。有关更简单的算法,请参见en.wikipedia.org/wiki/。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值