I have images with variable names, the only consistant feature/thing is that the image number is located at the end of the name, just before the extension. For example: "im1.png", "Image 02.tif", "My3rdImage_3.jpg" , "Whatever_17_MoreWhatever-31.tiff".
What would be the best way to find the last number?
I can always do:
- Find the last point.
- Go back while I detect digits
- Return the string between the last detected digit (included) and the point (excluded). But is there a better/faster/automatic way to do it?
CodePudding user response:
you can use re.findall
and find numbers then return last number.
import re
lst = ["im1.png", "Image 02.tif", "My3rdImage_3.jpg" , "Whatever_17_MoreWhatever-31.tiff"]
for l in lst:
print(re.findall(r'\d ', l)[-1])
Output:
1
02
3
31
Explanation:
>>> re.findall(r'\d ', "Whatever_17_MoreWhatever-31.tiff")
['17', '31']
CodePudding user response:
With the help of the re module you could do this:
import re
filenames = ["im1.png", "Image 02.tif", "My3rdImage_3.jpg" , "Whatever_17_MoreWhatever-31.tiff"]
for filename in filenames:
print(re.search('(\d )\D $', filename).group(1))
The expression matches a sequence of digits that precede a sequence of non-digits at the end of the string
Output:
1
02
3
31
CodePudding user response:
The most efficient and easiest way to use regular expressions, if you use a pre-compiled expression, the speed will be high performance and stability.
The example below implements the following algorithm, the regular expression looks for the end of the string - '$', then reads the file extension after '.\D*', and puts the number in matching group 1 '(\d*)'.
import re
regex = re.compile(r'(\d*)\.\D*$', re.X)
test_str = ("Whatever_17_MoreWhatever-31.tiff",
"My3rdImage_3.jpg",
"Image 02.tif",
"im1.png",
"im.png",
"foo",
"1357.137",
"–Æ–ù–ò–ö–û–î 12 22.txt")
for s in test_str:
num = None
match = regex.search(s)
if match:
num = match.group(1)
print(f"For string {s} last number is",
f"{num if num else 'empty'}")
More details can be read here: https://docs.python.org/3/howto/regex.html
CodePudding user response:
Don't know if it is "the best way" but you could do this with regex and it will automatically pick the last digit in a string:
EDIT
This pattern searches for any digit (or digits) which isn't followed by another digit in the string. So you always get the last number as a result.
With re.search
:
lst = ["im.png", "Image 02.tif", "My3rdImage_3.jpg" , "Whatever_17_MoreWhatever-31.tiff", "My4rdImage22_445.jpg"]
pat = r"(\d )(?!.*\d )"
for elem in lst:
tmp = re.search(pat, elem)
if tmp:
print(tmp[0])
02
3
31
445
Or (credit to @Mad Physicist) a pattern which searches for "A single group of digits followed by non-digits, then end-of-string"
lst = ["im.png", "Image 02.tif", "My3rdImage_3.jpg" , "Whatever_17_MoreWhatever-31.tiff", "My4rdImage22_445.jpg"]
pat = r"(\d )(?=\D*$)"
for elem in lst:
tmp = re.search(pat, elem)
if tmp:
print(tmp[0])
02
3
31
445
re.findall
import re
lst = ["im1.png", "Image 02.tif", "My3rdImage_3.jpg" , "Whatever_17_MoreWhatever-31.tiff"]
pattern = r"\d "
for elem in lst:
tmp = re.findall(pattern, elem)
print(tmp)
print(tmp[-1], '\n')
['1']
1
['02']
02
['3', '3']
3
['17', '31']
31
CodePudding user response:
Use filter
to get only the digits of a string
Use [-1]
to get the last character of a string.
last_number = filter(str.isdigit, text)[-1]