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.
Using str.endswith()
(Recommended)
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)
: ReturnsTrue
ifstring
ends exactly with the characters insuffix
, otherwiseFalse
. 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).
Using str.endswith()
with a Tuple (Recommended)
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).
Using Regular Expressions (re.search()
) (Recommended)
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 ifre.search
returned a match object (truthy) orNone
(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: Truere.search()
: Use there.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 there.IGNORECASE
flag withre.search()
.
Select the method that precisely matches the pattern or suffix you need to verify at the end of your string.