2

I got this code:

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

Which suppose to increase ONLY the last digit from the string given. But if you run that code you will see that if there is the same digit in the string as the last one it will increase it one after the other if you keep running the script. Can anyone help me find out why?

Thank you in advance for any help

4

4 に答える 4

8

代わりにこのようなことをしていない理由はありますか?

prefix, version = re.match(r"(.*[^\d]+)([\d]+)$", myString).groups()
newstring = prefix + str(int(version)+1).rjust(len(version), '0')

ノート:

  • これにより、実際にはバージョン番号が適切に「引き継がれ」ます:( "09"-> "10")および( "99"-> "100")
  • この正規表現は、最後の最終バージョンのサブストリングの前に少なくとも1つの非数字文字を想定しています。これが一致しない場合は、をスローしAttributeErrorます。より適切または特定の例外をスローするように再構築することができます(たとえば、re.match(...)returnsの場合None。詳細については、以下のコメントを参照してください)。

それに応じて調整します。

于 2012-04-13T03:08:28.797 に答える
2

問題は、list.index()5行目の関数の使用です。これにより、リスト内で最初に出現する値のインデックスが左から右に返されますが、コードはのリスト(右から左)を繰り返し処理しています。これをまっすぐにする方法はたくさんありますが、既存のコードへの変更を最小限に抑える方法は次のとおりです。インデックスを逆に繰り返します(リストを逆にすることは避けます)。

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
于 2012-04-13T03:05:11.037 に答える
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()

  • このコードは*、整数を受け入れて幅を設定するフォーマットテンプレートでを使用しています。

  • パターンを簡略化しました。数字を一致させているか(オプションの先行マイナス記号を使用)、または数字以外を一致させています。

  • 私はこれをテストしました、そしてそれはうまくいくようです。

于 2012-04-13T03:13:25.283 に答える
1

まず、3つのメモ:

  1. id予約済みのPythonワードです。
  2. 参加するために、よりpythonicイディオムは''.join()、リテラルの空の文字列を使用します
  3. 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
于 2012-04-13T03:19:00.497 に答える