Skip to main content

How to Check if String Ends With Substring, Number, or Multiple Strings in Python

Verifying the ending of a string is a common task in Python, useful for validating filenames, parsing URLs, checking data formats, or categorizing text. Python offers several ways to achieve this, from the simple str.endswith() method for exact matches to the more powerful re.search() for pattern matching (like checking for any number).

This guide demonstrates how to effectively check if a string ends with a specific substring, any number, or one of several possible suffixes.

Check if String Ends With Specific Substring

Goal: Determine if a string terminates with an exact sequence of characters.

The built-in str.endswith() method is the most direct and readable way to check for a specific suffix.

filename = "document_final_v2.docx"
target_suffix = ".docx"

# ✅ Check if the string ends with the suffix
ends_with_docx = filename.endswith(target_suffix)

print(f"String: '{filename}'")
print(f"Ends with '{target_suffix}'? {ends_with_docx}") # Output: True

# Example: False case
ends_with_pdf = filename.endswith(".pdf")
print(f"Ends with '.pdf'? {ends_with_pdf}") # Output: False
  • string.endswith(suffix): Returns True if string ends exactly with the characters in suffix, otherwise False. It's case-sensitive by default.

Using String Slicing

You can achieve this manually with slicing, but it's less readable than endswith().

filename = "document_final_v2.docx"
target_suffix = ".docx"

# ✅ Check using slicing
# Compare the end slice of filename with the target suffix
ends_with_slice = filename[-len(target_suffix):] == target_suffix

print(f"String: '{filename}'")
print(f"Ends with '{target_suffix}' (slicing)? {ends_with_slice}") # Output: True

# Important: Handle potential edge case where suffix is longer than string
long_suffix = "very_long_suffix.docx"
safe_check = len(filename) >= len(long_suffix) and filename[-len(long_suffix):] == long_suffix
print(f"Ends with '{long_suffix}' (safe slice)? {safe_check}") # Output: False
  • filename[-len(target_suffix):]: Slices the string starting from the position calculated by the negative length of the suffix up to the end.
  • Requires checking length first if the suffix might be longer than the string. endswith() handles this automatically.

Check if String Ends With One of Multiple Substrings

Goal: Determine if a string terminates with any of the suffixes provided in a collection (like a tuple or list).

The endswith() method conveniently accepts a tuple of suffixes as its first argument. It returns True if the string ends with any one of the strings in the tuple.

url = "https://example.com/image.png"
image_extensions = ('.jpg', '.jpeg', '.png', '.gif') # Suffixes in a tuple

# ✅ Pass the tuple of suffixes directly to endswith()
is_image_url = url.endswith(image_extensions)

print(f"URL: '{url}'")
print(f"Image Extensions: {image_extensions}")
print(f"Is image URL? {is_image_url}") # Output: True (ends with .png)

url_doc = "https://example.com/report.docx"
is_image_url_doc = url_doc.endswith(image_extensions)
print(f"URL: '{url_doc}'")
print(f"Is image URL? {is_image_url_doc}") # Output: False

This is the most concise and idiomatic way to check against multiple possible endings.

Using any() with a Generator Expression

You can achieve the same result using any() and a generator expression, checking endswith() for each suffix individually. This is more verbose but demonstrates the underlying logic.

url = "https://example.com/image.png"
image_extensions = ('.jpg', '.jpeg', '.png', '.gif')

# ✅ Use any() to check if endswith() is True for any suffix
is_image_any = any(url.endswith(suffix) for suffix in image_extensions)

print(f"URL: '{url}'")
print(f"Is image URL (any)? {is_image_any}") # Output: True

Check if String Ends With a Number (Any Digit)

Goal: Determine if the very last character(s) of a string are numeric digits (0-9).

Regular expressions are ideal for pattern matching like "one or more digits at the end". We use re.search() with a pattern ending in $, which anchors the match to the end of the string.

import re # Required import

string1 = "file_version_123"
string2 = "file_version_abc"
string3 = "version4"
string4 = "" # Empty string

# Regex pattern: \d+ means 'one or more digits'
# $ means 'at the end of the string'
pattern = r'\d+$'

# Test string 1
match1 = re.search(pattern, string1)
print(f"String: '{string1}'")
if match1:
print(f"Ends with number? Yes (Match: '{match1.group()}')") # Output: Yes (Match: '123')
else:
print("Ends with number? No")

# Test string 2
match2 = re.search(pattern, string2)
print(f"String: '{string2}'")
if match2:
print(f"Ends with number? Yes (Match: '{match2.group()}')")
else:
print("Ends with number? No") # Output: No

# Test string 3
match3 = re.search(pattern, string3)
print(f"String: '{string3}'")
if match3:
print(f"Ends with number? Yes (Match: '{match3.group()}')") # Output: Yes (Match: '4')
else:
print("Ends with number? No")

# Test string 4 (Empty)
match4 = re.search(pattern, string4)
print(f"String: '{string4}'")
if match4:
print(f"Ends with number? Yes (Match: '{match4.group()}')")
else:
print("Ends with number? No") # Output: No
  • re.search(pattern, string): Returns a match object if the pattern is found anywhere, None otherwise.
  • r'\d+$': The pattern. \d matches any digit. + means "one or more" of the preceding element (\d). $ anchors the match to the very end of the string.
  • if match1:: Checks if re.search returned a match object (truthy) or None (falsy).
  • match1.group(): If a match exists, this returns the actual matched substring (the number at the end).

Using Indexing and str.isdigit()

You can check if the last character is a digit. This only works reliably if you expect exactly one digit at the end or don't care about preceding non-digits.

def ends_with_single_digit(input_str):
"""Checks if the very last character is a digit."""
# Check if string is not empty AND last character is a digit
return bool(input_str and input_str[-1].isdigit())

# Example Usage
string1 = "item_code_5"
string2 = "item_code_12" # Ends in a digit, but method only checks the last one
string3 = "item_code_X"
string4 = ""

print(f"'{string1}': Ends with single digit? {ends_with_single_digit(string1)}") # Output: True
print(f"'{string2}': Ends with single digit? {ends_with_single_digit(string2)}") # Output: True
print(f"'{string3}': Ends with single digit? {ends_with_single_digit(string3)}") # Output: False
print(f"'{string4}': Ends with single digit? {ends_with_single_digit(string4)}") # Output: False
  • input_str[-1]: Accesses the last character. Negative indexing counts from the end.
  • .isdigit(): Checks if that single character is a digit.
  • bool(input_str and ...): Safely handles empty strings (an empty string is falsy, so the check short-circuits).
  • Limitation: This doesn't verify if there are multiple digits at the end (like in item_code_12) or handle cases where non-digits precede the final digit. Regex (\d+$) is better for "ends with one or more digits".

Check if String Ends With Specific Number(s) (Using endswith)

If you need to check if a string ends with a specific number represented as a string, endswith() is the appropriate tool.

log_entry = "transaction_id_12345"
error_code = "process_failed_99"

# Check for specific numeric endings (as strings)
ends_with_12345 = log_entry.endswith("12345")
print(f"'{log_entry}': Ends with '12345'? {ends_with_12345}") # Output: True

# Check against multiple specific numeric endings (pass a tuple of strings)
error_codes = ("_99", "_101", "_500")
is_known_error = error_code.endswith(error_codes)
print(f"'{error_code}': Ends with {error_codes}? {is_known_error}") # Output: True

Case-Insensitive Checks

  • endswith(): Does not have a built-in case-insensitivity flag. You must convert both the string and the suffix(es) to the same case first:
    filename = "Report.PDF"
    suffixes = (".pdf", ".docx")
    # ✅ Convert both to lowercase for comparison
    match = filename.lower().endswith(tuple(s.lower() for s in suffixes))
    print(f"'{filename}' ends with {suffixes} (insensitive)? {match}") # Output: True
  • re.search(): Use the re.IGNORECASE flag:
    import re
    text = "Image.JPEG"
    # ✅ Add re.IGNORECASE flag
    match_re = re.search(r'\.jpeg$', text, flags=re.IGNORECASE)
    print(f"'{text}' ends with '.jpeg' (regex insensitive)? {bool(match_re)}") # Output: True

Conclusion

Checking string endings in Python involves choosing the right tool:

  • For exact, specific suffixes: Use str.endswith(suffix).
  • For checking against multiple specific suffixes: Use str.endswith((suffix1, suffix2, ...)) with a tuple.
  • For checking if the string ends with any number (one or more digits): Use re.search(r'\d+$', string).
  • For checking if the very last character is a digit: Use slicing and string[-1].isdigit() (handle empty strings).
  • For case-insensitive checks: Convert strings to lowercase/uppercase before using endswith(), or use the re.IGNORECASE flag with re.search().

Select the method that precisely matches the pattern or suffix you need to verify at the end of your string.