如何在python中增加字母数字?

Posted

技术标签:

【中文标题】如何在python中增加字母数字?【英文标题】:How to increment alphanumeric number in python? 【发布时间】:2020-05-19 05:30:25 【问题描述】:

我正在创建一个由 16 个字母数字字符组成的密码,其中我生成从 A001、A002、A003 到 A999 的 4 位数字。一旦到 A999,字母将自动增加到 B,数字将再次以 001 开头。同样的过程将一直到 Z999。一旦 A-Z 系列结束,就会从 AA01 开始,以此类推。如何在python中做这件事?由于我是 python 新手,所以我自己尝试过,也尝试了一些示例,但我无法增加字符。 任何想法或想法将不胜感激。

非常感谢

rec=0
new_list16 = []
def autoIncrement():
    global rec
    first = 'A'
    i = chr(ord(first))
    new_list16.append(i)

    while True:
        pStart = 1 #adjust start value, if req'd 
        pInterval = 1 #adjust interval value, if req'd
        if (rec == 0):
            rec += pStart
        else:
            rec = rec + pInterval
        return str(rec).zfill(3)
#print(autoIncrement())
new_list16.append(autoIncrement())

print(*new_list16, sep = '')

【问题讨论】:

使用 this 表示 A-Z 部分; 001 部分只是模 1000 的数字。 从 A999 到 B001 而不是 B000 真的把事情搞砸了...... 【参考方案1】:

A999B001 而不是B000 确实有点搞砸了,但您仍然可以将this 用于A-Z 部分,并对数字进行简单的模运算。

def excel_format(num):
    # see https://***.com/a/182924/1639625
    res = ""
    while num:
        mod = (num - 1) % 26
        res = chr(65 + mod) + res
        num = (num - mod) // 26
    return res

def full_format(num, d=3):
    chars = num // (10**d-1) + 1 # this becomes   A..ZZZ
    digit = num %  (10**d-1) + 1 # this becomes 001..999
    return excel_format(chars) + ":0d".format(digit, d)

for i in range(10000):
    print(i, full_format(i, d=2))

数字部分的位数由可选的d 参数控制。我将使用2 进行演示,但3 也可以。

0 A01
...
98 A99
99 B01
...
2573 Z99
2574 AA01
...
9998 CW99
9999 CX01

【讨论】:

在 Z999 之前它完全可以正常工作,之后它会打印 5 位数字,而我只想要 4 位数字。 Z999 之后的下一个数字应该是 AA01。不是AA001 @rajatmaan 啊,以为是错字。这使得这一切变得更加复杂。还有,ZZZZ9之后会发生什么,是ZZZZA继续,然后在ZZZZZ结束? 请查看我今天上传的答案。到 ZZ99 为止都是 4 位数字。【参考方案2】:
def auto_increment(number):
    if number == 'ZZZZ':
        return 'ZZZZ'

    digits = "".join([i for i in number if i.isdigit()])
    chars = "".join([i for i in number if not i.isdigit()])
    if int(digits) == int('9' * len(digits)):
        digits = "000"
        new_char = [ord(i) for i in chars]
        if new_char[-1] % ord('Z') == 0:
            new_char = "".join([chr(i) for i in new_char]) + 'A'
        else:
            new_char[-1] = new_char[-1] + 1
            new_char = "".join([chr(i) for i in new_char])
    else:
        new_char = chars

    new_digit = int(digits) + 1
    l = len(new_char) 
    ll = len(str(new_digit))
    new_digit = (("0" * (3-ll)) + str(new_digit))[(l-1):]
    return f"new_charnew_digit"

这个函数返回下一个数字,给定任何数字。 例如:A999 将返回 AB01。

你现在可以循环使用这个函数了。

【讨论】:

先生,它也可以正常工作。但问题是Z999之后,数字应该保持不变,但它会变为5位。 我可以使用函数来实现吗,因为这个密钥工作包含在运行函数中。 在 Z999 之后,它应该转到 ZA01,因为我们在数字后面使用字母。它工作得很好。它永远不会达到 5 位数,您是否尝试过运行它?你也可以选择它作为正确答案。【参考方案3】:

这可能需要更多的测试和重构,但这里是你的开始:

def leadingZeros(number, digits):
    numberString = str(number)
    for digit in range(1, digits):
        if number < 10**digit:
            numberString = '0' + numberString
    return numberString


def autoIncrement(oldNumber):
    order = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ!'
    lastDigitOrder = order.find(oldNumber[3])
    newNumber = ''
    if order.find(oldNumber[1]) <= 9:
        # 3 digit number
        number = int(oldNumber[1:]) + 1
        letter = oldNumber[0]
        if 1000 == number:
            letterOrder = order.find(oldNumber[0])
            letter = order[letterOrder + 1]
        newNumber = letter + leadingZeros(number % 1000, 3)
    elif order.find(oldNumber[2]) <= 9:
        # 2 digit number
        number = int(oldNumber[2:]) + 1
        letters = oldNumber[0:2]
        if 100 == number:
            letterOrder = order.find(oldNumber[1])
            letter = order[letterOrder + 1]
            letters = oldNumber[0] + letter
        newNumber = letters + leadingZeros(number % 100, 2)
    elif order.find(oldNumber[3]) <= 9:
        # 1 digit number
        number = int(oldNumber[3]) + 1
        letters = oldNumber[0:3]
        if 10 == number:
            letterOrder = order.find(oldNumber[2])
            letter = order[letterOrder + 1]
            letters = oldNumber[0:2] + letter
        newNumber = letters + leadingZeros(number % 10, 1)
    else:
        # just letters
        print(oldNumber)
        letterOrder = order.find(oldNumber[3])
        letter = order[letterOrder + 1]
        newNumber = oldNumber[0:3] + letter

    # if one of the digits has gone past Z then we need to update the letters
    if '!' == newNumber[3]:
        # past Z in 4th digit
        letterOrder = order.find(oldNumber[2])
        newNumber = newNumber[0:2] + order[letterOrder + 1] + 'A'
    if '!' == newNumber[2]:
        # past Z in 3rd digit
        letterOrder = order.find(oldNumber[1])
        newNumber = newNumber[0:1] + order[letterOrder + 1] + 'A' + newNumber[3]
    if '!' == newNumber[1]:
        # past Z in 2nd digit
        letterOrder = order.find(oldNumber[0])
        newNumber = order[letterOrder + 1] + 'A' + newNumber[2:]

    return newNumber


print(autoIncrement('A999'))
print(autoIncrement('AA99'))
print(autoIncrement('AAA9'))
print(autoIncrement('AAAA'))
print(autoIncrement('AZZ9'))

【讨论】:

【参考方案4】:

这不是您所要求的,但如果您的要求是 4 个字符的“顺序”字符串,让我建议一个更简单的方法。为什么不简单地使用以 36 为基数的数字呢?也就是说,让您的数字从0, 1, 2, ... A, B, C, ... Z, 10, 11, 12, ... 1Z, ... 开始,然后将基数 36 字符串之一转换为 int,只需:

n = int('12AV', 36)

并将 int 转换为基数 n 字符串:

def baseN(num, base, numerals="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"):
      return ((num == 0) and numerals[0]) or (baseN(num // base, base, numerals).lstrip(numerals[0]) + numerals[num % base])

把它们放在一起:

n = int('12AV', 36)
s = baseN(n + 1, 36)
print(s)

打印:

12AW

当然,如果需要,您可以从“A001”开始。然后,您将在 35 次迭代后转到 A00Z。您最终将生成与原始方法相同的数字,只是顺序不同。

【讨论】:

【参考方案5】:

感谢您提供的解决方案。但是我尝试了一些我想要的问题。请检查它并给你的cmets。

def full_format(i):
    # limit of first range is 26 letters (A-Z) times 999 numbers (001-999)
    if i < 26 * 999:
        c,n = divmod(i,999)   # quotient c is index of letter 0-25, remainder n is 0-998
        c = chr(ord('A') + c) # compute letter
        n += 1
        return f'cn:03'
    # After first range, second range is 26 letters times 26 letters * 99 numbers (01-99)
    elif i < 26*999 + 26*26*99:
        i -= 26*999               # remove first range offset
        cc,n = divmod(i,99)       # remainder n is 0-98, use quotient cc to compute two letters
        c1,c2 = divmod(cc,26)     # c1 is index of first letter, c2 is index of second letter
        c1 = chr(ord('A') + c1)   # compute first letter
        c2 = chr(ord('A') + c2)   # compute second letter
        n += 1
        return f'c1c2n:02'
    else:
        raise OverflowError(f'limit is 26*999+26*26*99')

for i in range(92880, 92898):
    print(full_format(i))

【讨论】:

以上是关于如何在python中增加字母数字?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用字母和数字自动增加 ID 编号

如何在 Python 中增加数字字符串

如何在python中用数字、字母和空格分割字符串?

如何在 Python 中测试正则表达式密码?

Python regex如何在字母和数字之间插入连字符;并删除两个字母之间的连字符

Python正则表达式 | 如何只提取中文英文字母数字(含科学计数法)