我想知道在Python中是否有类似于Ruby的String#succ方法的函数(或方法),即:
~ $ irb --simple-prompt
>> '2'.succ
=> "3"
>> '99'.succ
=> "100"
>> 'zzz'.succ
=> "aaaa"
>>
我想知道在Python中是否有类似于Ruby的String#succ方法的函数(或方法),即:
~ $ irb --simple-prompt
>> '2'.succ
=> "3"
>> '99'.succ
=> "100"
>> 'zzz'.succ
=> "aaaa"
>>
def succ(s):
if not isinstance(s, (str,string)):
raise TypeError("succ works only with strings")
if not s: return
if max(map(ord, s)) > 127:
raise TypeError("succ currently only supports ascii")
#Three different character category honoured
# 1. ascii lowercase alpha
# 2. ascii uppercase alpha
# 3. digits
# 4. ascii nonalpha characters (the entire ascii set)
lower = string.ascii_lowercase + 'a'
upper = string.ascii_uppercase + 'A'
digits = string.digits + '0'
nonalpha = map(chr, range(0, 256)) + [chr(0)]
def incr(ch):
'''
Generates the next character in sequence using the following rules
1. Incrementing a digit always results in another digit
2. Incrementing a letter results in another letter of the same case.
3. Incrementing nonalphanumerics uses the underlying
character set’s collating sequence.
'''
if ch.isdigit(): return digits[ord(ch) - ord("0") + 1]
if ch.islower(): return lower[ord(ch) - ord('a') + 1]
if ch.isupper(): return upper[ord(ch) - ord('A') + 1]
return nonalpha[ord(ch) + 1]
def last(ch):
'''
Returns the last character in its catagory
'''
if ch.isdigit(): return digits[-2]
if ch.islower(): return lower[-2]
if ch.isupper(): return upper[-2]
return nonalpha[-2]
def first(ch):
'''
Returns the last first in its catagory
'''
if ch.isdigit(): return digits[0]
if ch.islower(): return lower[0]
if ch.isupper(): return upper[0]
return nonalpha[0]
def islast(ch):
'''
Checks if next increment would generate a carry
'''
return ch == last(ch)
s = list(s)[::-1]
carry = True
try:
index = next(i for i, e in enumerate(s) if e.isalnum())
except StopIteration:
index = 0
while carry:
if index == len(s): #Add a character for Overflow
s.append(first(s[index - 1]))
break
carry = True if islast(s[index]) else False
s[index] = incr(s[index])
index += 1
return ''.join(s[::-1])
succ('2') - > 3
succ('99') - > 000
succ('zzz') - > aaaa
succ('') - > None
succ('abcd') - > abce
succ('THX1138') - > THX1139
succ('<<koala>>') - > <<koalb>>
succ('1999zzz') - > 2000aaa
succ('ZZZ9999') - > AAAA0000
succ('***') - > **+
'zzz'.succ
会返回'aaaa'
。这完全取决于地区设置。例如,在丹麦,它可能应该返回'ååå'
,因为å
被视为一个单独的字母,排在z
之后。 - Denis de Bernardy