Reputation: 377
I was writing a little program that finds all files with given prefix, let's say 'spam'
for this example, in a folder and locates gaps in numbering and renames subsequent folders to fill the gap. Below illustrates a portion of the program that locates the files using a regex and renames it:
prefix = 'spam'
newNumber = 005
# Regex for finding files with specified prefix + any numbering + any file extension
prefixRegex = re.compile(r'(%s)((\d)+)(\.[a-zA-Z0-9]+)' % prefix)
# Rename file by keeping group 1 (prefix) and group 4 (file extension),
# but substituting numbering with newNumber
newFileName = prefixRegex.sub(r'\1%s\4' % newNumber, 'spam006.txt')
What I was expecting from above was spam005.txt
, but instead I got @5.txt
I figured out I could use r'%s%s\4' % (prefix, newNumber)
instead and then it does work as intended, but I'd like to understand why this error is happening. Does it have something to do with the %s
used during re.compile()
?
Upvotes: 1
Views: 37
Reputation: 3575
There are two problems here:
Your newNumber
needs to be a string if you want it to be 005
as the first two 0
are dropped when it is being interpreted as an integer.
Your next problem is indeed in your substitution. By using the string formating you effectively create the new regexp \15\4
(see the 5
in there, that was your newNumber
). When python sees this it tries to get capturing group 15
and not group 1
followed by a literal 5
. You can enclose the reference in a g
like this to get your desired behavior: \g<1>5\4
So your code needs to be changed to this:
prefix = 'spam'
newNumber = '005'
# Regex for finding files with specified prefix + any numbering + any file extension
prefixRegex = re.compile(r'(%s)((\d)+)(\.[a-zA-Z0-9]+)' % prefix)
# Rename file by keeping group 1 (prefix) and group 4 (file extension),
# but substituting numbering with newNumber
newFileName = prefixRegex.sub(r'\g<1>%s\4' % newNumber, 'spam006.txt')
More information about the \g<n>
behavior can be found at the end of the re.sub
doucmentation
Upvotes: 1