Python startswith() / endswith()

startswith()endswith() 用來檢查字串是否以特定子字串開頭或結尾。

startswith() - 檢查開頭

text = "Hello World"

print(text.startswith("Hello"))  # True
print(text.startswith("World"))  # False
print(text.startswith("Hi"))     # False

endswith() - 檢查結尾

text = "Hello World"

print(text.endswith("World"))    # True
print(text.endswith("Hello"))    # False
print(text.endswith("ld"))       # True

語法

str.startswith(prefix, start=0, end=len(str))
str.endswith(suffix, start=0, end=len(str))
  • prefix / suffix:要檢查的子字串,可以是字串或 tuple
  • start:檢查起始位置(選填)
  • end:檢查結束位置(選填)

檢查多個選項

使用 tuple 可以同時檢查多個可能的開頭或結尾:

filename = "image.png"

# 檢查是否為圖片檔案
print(filename.endswith((".png", ".jpg", ".gif")))  # True

# 檢查協定
url = "https://example.com"
print(url.startswith(("http://", "https://")))  # True

指定檢查範圍

text = "Hello World"

# 從索引 6 開始檢查
print(text.startswith("World", 6))    # True
print(text.startswith("Hello", 6))    # False

# 在索引 0-5 範圍內檢查
print(text.endswith("Hello", 0, 5))   # True
print(text.endswith("World", 0, 5))   # False

大小寫敏感

這兩個方法是大小寫敏感的:

text = "Hello World"

print(text.startswith("hello"))  # False
print(text.startswith("Hello"))  # True

# 不區分大小寫的檢查
print(text.lower().startswith("hello"))  # True

實際範例

檢查檔案類型

def is_image(filename):
    return filename.lower().endswith((".png", ".jpg", ".jpeg", ".gif", ".bmp"))

def is_video(filename):
    return filename.lower().endswith((".mp4", ".avi", ".mkv", ".mov"))

print(is_image("photo.JPG"))     # True
print(is_image("document.pdf"))  # False
print(is_video("movie.mp4"))     # True

檢查 URL 協定

def is_secure_url(url):
    return url.lower().startswith("https://")

def is_valid_url(url):
    return url.lower().startswith(("http://", "https://"))

print(is_secure_url("https://example.com"))  # True
print(is_secure_url("http://example.com"))   # False
print(is_valid_url("http://example.com"))    # True

過濾檔案列表

files = [
    "main.py",
    "test_main.py",
    "utils.py",
    "test_utils.py",
    "config.json",
    "README.md"
]

# 找出所有 Python 檔案
python_files = [f for f in files if f.endswith(".py")]
print(python_files)  # ['main.py', 'test_main.py', 'utils.py', 'test_utils.py']

# 找出所有測試檔案
test_files = [f for f in files if f.startswith("test_")]
print(test_files)    # ['test_main.py', 'test_utils.py']

處理路徑

def ensure_trailing_slash(path):
    if not path.endswith("/"):
        return path + "/"
    return path

def remove_trailing_slash(path):
    return path.rstrip("/")

print(ensure_trailing_slash("/home/user"))    # /home/user/
print(ensure_trailing_slash("/home/user/"))   # /home/user/
print(remove_trailing_slash("/home/user/"))   # /home/user

檢查電話號碼

def is_taiwan_phone(phone):
    return phone.startswith(("09", "+8869"))

print(is_taiwan_phone("0912345678"))    # True
print(is_taiwan_phone("+886912345678")) # True
print(is_taiwan_phone("0212345678"))    # False

處理註解

def is_comment(line):
    stripped = line.strip()
    return stripped.startswith("#") or stripped.startswith("//")

lines = [
    "print('hello')",
    "# This is a comment",
    "  // Another comment",
    "x = 10"
]

for line in lines:
    if not is_comment(line):
        print(line.strip())

輸出:

print('hello')
x = 10

解析 INI 格式

def parse_ini_line(line):
    line = line.strip()
    
    if line.startswith("[") and line.endswith("]"):
        return ("section", line[1:-1])
    elif "=" in line:
        key, value = line.split("=", 1)
        return ("setting", key.strip(), value.strip())
    return ("other", line)

lines = [
    "[database]",
    "host = localhost",
    "port = 5432"
]

for line in lines:
    result = parse_ini_line(line)
    print(result)

輸出:

('section', 'database')
('setting', 'host', 'localhost')
('setting', 'port', '5432')

和其他方法比較

text = "Hello World"

# 使用 startswith()
if text.startswith("Hello"):
    print("Starts with Hello")

# 使用 slice(較不直觀)
if text[:5] == "Hello":
    print("Starts with Hello")

# 使用 find()(較不直觀)
if text.find("Hello") == 0:
    print("Starts with Hello")

startswith()endswith() 是最清晰、最 Pythonic 的方式。