Reputation: 67
I am working on a script to rename files. In this scenario there are three possibilities.
1.file does not exist: Create new file
2.File exists: create new file with filename '(number of occurence of file)'.eg filename(1)
3.Duplicate of file already exists: create new file with filename '(number of occurence of file)'.eg filename(2)
I have the filename in a string. I can check the last character of filename using regex but how to check the last characters from '(' to ')' and get the number inside it?
Upvotes: 1
Views: 129
Reputation: 2348
Here is the code and tests to get a filename based on existing filenames:
import re
def get_name(filename, existing_names):
exist = False
index = 0
p = re.compile("^%s(\((?P<idx>\d+)\))?$" % filename)
for name in existing_names:
m = p.match(name)
if m:
exist = True
idx = m.group('idx')
if idx and int(idx) > index:
index = int(idx)
if exist:
return "%s(%d)" % (filename, index + 1)
else:
return filename
# test data
exists = ["abc(1)", "ab", "abc", "abc(2)", "ab(1)", "de", "ab(5)"]
tests = ["abc", "ab", "de", "xyz"]
expects = ["abc(3)", "ab(6)", "de(1)", "xyz"]
print exists
for name, exp in zip(tests, expects):
new_name = get_name(name, exists)
print "%s -> %s" % (name, new_name)
assert new_name == exp
Look at this line for the regex to get the number in (*)
:
p = re.compile("^%s(\((?P<idx>\d+)\))?$" % filename)
Here it uses a named capture ?P<idx>\d+
for the number \d+
, and access the capture later with m.group('idx')
.
Upvotes: 0
Reputation: 44831
You just need something like this:
(?<=\()(\d+)(?=\)[^()]*$)
Explanation:
(?<=\()
must be preceded by a literal (
(\d+)
match and capture the digits(?=\)[^()]+$)
must be followed by )
and then no more (
or )
until the end of the string.Example: if the file name is Foo (Bar) Baz (23).jpg
, the regex above matches 23
Upvotes: 2