Skip to content

建立 2026-09-15 更新 2026-09-15

驗證格式

驗證用 re.fullmatch,不要只用 searchsearch 只要「裡面有一段像」就過;使用者在信箱後面多打一堆字也會被當成合法。

簡易電子郵件

完整的 RFC 規格極長,實務上用「夠用的形狀」即可,真正能不能寄還是要發信確認。

import re

EMAIL = re.compile(
    r"^[\w.+-]+@[\w-]+(?:\.[\w-]+)+$",
    re.IGNORECASE,
)

def looks_like_email(value: str) -> bool:
    return EMAIL.fullmatch(value.strip()) is not None

assert looks_like_email("ada@vcdemy.com")
assert looks_like_email("Ada.Lovelace@example.org")
assert not looks_like_email("ada@")
assert not looks_like_email("ada vcdemy.com")

台灣手機

常見寫法是 09 開頭共 10 碼,中間可有 -

import re

TW_MOBILE = re.compile(r"^09\d{2}-?\d{3}-?\d{3}$")

def looks_like_tw_mobile(value: str) -> bool:
    compact = value.strip().replace(" ", "")
    return TW_MOBILE.fullmatch(compact) is not None

assert looks_like_tw_mobile("0912-345-678")
assert looks_like_tw_mobile("0912345678")
assert not looks_like_tw_mobile("0212345678")
assert not looks_like_tw_mobile("0912-34-5678")

市話區碼長度不一,不要跟手機共用同一條模式。

日期 YYYY-MM-DD

regex 可以檢查「四碼-兩碼-兩碼」,不會自動排除 2026-02-31。月份日期要嘛在 Python 再用 datetime 驗,要嘛接受「形狀對了再交給解析函式」。

import re
from datetime import date

DATE = re.compile(r"^(\d{4})-(\d{2})-(\d{2})$")

def parse_iso_date(value: str) -> date | None:
    m = DATE.fullmatch(value.strip())
    if not m:
        return None
    year, month, day = map(int, m.groups())
    try:
        return date(year, month, day)
    except ValueError:
        return None

assert parse_iso_date("2026-09-15") == date(2026, 9, 15)
assert parse_iso_date("2026-02-31") is None
assert parse_iso_date("15/09/2026") is None

網址(http / https)

import re

URL = re.compile(
    r"^https?://[\w.-]+(?:/[\w./%?&=~-]*)?$",
    re.IGNORECASE,
)

assert URL.fullmatch("https://www.vcdemy.com/regex")
assert URL.fullmatch("http://localhost")
assert not URL.fullmatch("javascript:alert(1)")

這條拒絕 javascript: 這類非 http 協定,但仍不是完整 URL 剖析。正式專案用 urllib.parse

密碼形狀(僅示範)

import re

# 至少 8 字,含大寫、小寫、數字
PASSWORD = re.compile(
    r"^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,}$"
)

assert PASSWORD.fullmatch("Abcd1234")
assert not PASSWORD.fullmatch("abcd1234")
assert not PASSWORD.fullmatch("Abcd12")

先行斷言在這裡檢查「後面某個地方有這類字」,本身不消耗字元。密碼還需要雜湊存放與外洩檢查;regex 只看形狀。

相關資料