我收到了这段代码:
myString = 'blabla123_01_version6688_01_01Long_stringWithNumbers'
versionSplit = re.findall(r'-?\d+|[a-zA-Z!@#$%^&*()_+.,<>{}]+|\W+?', myString)
for i in reversed(versionSplit):
id = versionSplit.index(i)
if i.isdigit():
digit = '%0'+str(len(i))+'d'
i = int(i) + 1
i = digit % i
versionSplit[id]=str(i)
break
final = ''
myString = final.join(versionSplit)
print myString
假设只增加给定字符串的最后一位数字。但是如果运行该代码,您将看到如果字符串中的数字与最后一个数字相同,那么如果您继续运行该脚本,它将一个接一个地增加它。任何人都可以帮我找出原因吗?
提前感谢您的任何帮助
答案 0 :(得分:8)
你有没有理由不做这样的事情:
prefix, version = re.match(r"(.*[^\d]+)([\d]+)$", myString).groups()
newstring = prefix + str(int(version)+1).rjust(len(version), '0')
注意:
AttributeError
。您可以重新构建它以引发更合适或特定的例外(例如,如果re.match(...)
返回None
;请参阅下面的评论以获取更多信息)。相应调整。
答案 1 :(得分:2)
问题是在第5行使用list.index()
函数。这会从列表中返回第一次出现的值,从左到右,但是代码迭代颠倒的列表(从右到左)。有很多方法可以解决这个问题,但这里有一个对现有代码进行最少更改的方法:反向迭代索引(避免反转列表)。
for idx in range(len(versionSplit)-1, -1, -1):
i = versionSplit[idx]
if chunk.isdigit():
digit = '%0'+str(len(i))+'d'
i = int(i) + 1
i = digit % i
versionSplit[idx]=str(i)
break
答案 2 :(得分:1)
myString = 'blabla123_01_version6688_01_01veryLong_stringWithNumbers01'
versionSplit = re.findall(r'-?\d+|[^\-\d]+', myString)
for i in xrange(len(versionSplit) - 1, -1, -1):
s = versionSplit[i]
if s.isdigit():
n = int(s) + 1
versionSplit[i] = "%0*d" % (len(s), n)
break
myString = ''.join(versionSplit)
print myString
注意:
使用.index()
方法尝试查找字符串是很愚蠢的。只需使用递减索引来尝试versionSplit
的每个部分。这就是你的问题所在,正如上面@David Robinson所评论的那样。
不要将id
用作变量名;你掩盖了内置函数id()
。
此代码在格式模板中使用*
,该模板将接受整数并设置宽度。
我简化了模式:要么匹配一个数字(带有可选的前导减号),要么就是匹配非数字。
我对此进行了测试,似乎有效。
答案 3 :(得分:1)
首先,三个注释:
id
是一个保留的python字; ''.join()
更加pythonic成语reversed()
返回迭代器,而不是列表。这就是我使用list(reversed())
的原因,以便稍后rev.index(i)
。更正后的代码:
import re
myString = 'blabla123_01_version6688_01_01veryLong_stringWithNumbers01'
print myString
versionSplit = re.findall(r'-?\d+|[a-zA-Z!@#$%^&*()_+.,<>{}]+|\W+?', myString)
rev = list(reversed(versionSplit)) # create a reversed list to work with from now on
for i in rev:
idd = rev.index(i)
if i.isdigit():
digit = '%0'+str(len(i))+'d'
i = int(i) + 1
i = digit % i
rev[idd]=str(i)
break
myString = ''.join(reversed(rev)) # reverse again only just before joining
print myString