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
How to increment letters like numbers in 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 a
to y
.
这将打印出从a
到的字母y
。
for($i = 'a'; $i <= 'z'; $i++) print "$i ";
This will print out lettes from a
to z
and it continues with aa
and ends with yz
.
这将从a
to打印出字母z
,aa
并以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'
ord()
converts the letter into ASCII num representation- that num representation is incremented
- using
chr()
the number gets converted back to the letter
ord()
将字母转换为 ASCII num 表示- 该 num 表示增加
- 使用
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 z
became 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-mbstring
extension: 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('!',ENT_NOQUOTES,'UTF-8');
/* ! */
echo html_entity_decode('"',ENT_NOQUOTES,'UTF-8');
/* " */
To retrieve the unicode symbol,using the base10decimal representation of the character.
要检索unicode符号,请使用字符的base10十进制表示。
echo html_entity_decode('€',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^0
Use 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^2
to get third digit, the remainder (modulo) by b^1
for 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.
回答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 中使用++
,很好!