Welcome, guest | Sign In | My Account | Store | Cart

Suppose one reference number on your invoice is "XYZ-001", then let this algorithm figure out that the next one should be "XYZ-002" or that "dsc_010.jpg" should become "dsc_011.jpg"

Python, 23 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import re
from string import zfill
numbers = re.compile('\d+')

def increment(s):
    """ look for the last sequence of number(s) in a string and increment """
    if numbers.findall(s):
        lastoccr_sre = list(numbers.finditer(s))[-1]
        lastoccr = lastoccr_sre.group()
        lastoccr_incr = str(int(lastoccr) + 1)
        if len(lastoccr) > len(lastoccr_incr):
            lastoccr_incr = zfill(lastoccr_incr, len(lastoccr))
        return s[:lastoccr_sre.start()]+lastoccr_incr+s[lastoccr_sre.end():]

    return s

def T(_):
    print "from",_, "to", increment(_)
if __name__=='__main__':
    T("10dsc_0010.jpg")
    T("dsc_9.jpg")
    T("0000001.exe")
    T("ref-04851")

It works at least. Perhaps I haven't used the SRE's returned correctly but perhaps by posting this recipe I can get some feedback on that.

1 comment

Chris Olds 18 years, 5 months ago  # | flag

Simplification. Here's my version, which I think is simpler.

/cco

import re
lastNum = re.compile(r'(?:[^\d]*(\d+)[^\d]*)+')

def increment(s):
    """ look for the last sequence of number(s) in a string and increment """
    m = lastNum.search(s)
    if m:
        next = str(int(m.group(1))+1)
        start, end = m.span(1)
        s = s[:max(end-len(next), start)] + next + s[end:]
    return s

def T(_):
    print "from",_, "to", increment(_)
if __name__=='__main__':
    T("10dsc_0010.jpg")
    T("10dsc_0099.jpg")
    T("dsc_9.jpg")
    T("0000001.exe")
    T("9999999.exe")
    T("ref-04851")