Home > Back-end >  Best way to find the last number in a String
Best way to find the last number in a String

Time:07-10

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]
  • Related