Email 格式驗證是表單處理的基礎功能。本文深度解析一個常用的 Email 正則模式,並提供 PHP 與 JavaScript 實作範例,同時說明為何現代專案建議改用內建驗證函式。
/^[a-z]([a-z0-9]*[-_.]?[a-z0-9]+)*@([a-z0-9]*[-_]?[a-z0-9]+)+\.[a-z]{2,3}(\.[a-z]{2})?$/i
| 片段 | 正則 | 說明 |
|---|---|---|
| 修飾符 | /.../i | i 忽略大小寫 |
| 錨點 | ^ ... $ | 完整字串匹配,不允許前後多餘字元 |
| 本地部開頭 | [a-z] | 必須以英文字母開頭 |
| 本地部主體 | ([a-z0-9]*[-_.]?[a-z0-9]+)* | 允許英數、底線、連字號、點號;特殊符號不可連續、不可首尾 |
| @ 符號 | @ | 必須包含單一 @ |
| 域名主體 | ([a-z0-9]*[-_]?[a-z0-9]+)+ | 至少一個域名標籤,規則同本地部但無點號 |
| 頂級域 | \.[a-z]{2,3} | .com .net .org 等 2-3 字母 |
| 二級域 (可選) | (\.[a-z]{2})? | .cn .tw .jp 等 2 字母國家碼 |
<?php
function validateEmail($email) {
// 使用 filter_var 內建驗證 (PHP 5.2+ 推薦)
if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
return true;
}
// 若需自訂更嚴格規則,可使用正則
$pattern = '/^[a-z]([a-z0-9]*[-_.]?[a-z0-9]+)*@([a-z0-9]*[-_]?[a-z0-9]+)+\.[a-z]{2,3}(\.[a-z]{2})?$/i';
return (bool)preg_match($pattern, $email);
}
// 測試
$tests = [
'user@example.com' => true,
'user.name@sub.domain.org' => true,
'user-name@domain.co.uk' => true,
'123@domain.com' => false, // 數字開頭
'user@domain' => false, // 缺頂級域
'user@.com' => false, // 域名標籤為空
];
foreach ($tests as $email => $expected) {
$result = validateEmail($email) ? '通過' : '失敗';
echo "$email : $result (預期: " . ($expected ? '通過' : '失敗') . ")\n";
}
?>
<script>
function validateEmailJS(email) {
// 簡易版:\w+@\w+\.\w+(\.\w+)*
// 較嚴格版:對應 PHP 正則
var regex = /^[a-z]([a-z0-9]*[-_.]?[a-z0-9]+)*@([a-z0-9]*[-_]?[a-z0-9]+)+\.[a-z]{2,3}(\.[a-z]{2})?$/i;
return regex.test(email);
}
console.log(validateEmailJS('test@example.com')); // true
console.log(validateEmailJS('invalid@domain')); // false
console.log(validateEmailJS('user@sub.domain.co.uk')); // true
</script>
在字串中表示正則時,反斜線需雙重轉義:
// JavaScript 字串寫法
var pattern = "^\\w+@\\w+\\.\\w+(\\.\\w+)*$";
// 實際正則:/^\w+@\w+\.\w+(\.\w+)*$/
// PHP 字串寫法 (單引號無需雙重轉義)
$pattern = '/^\w+@\w+\.\w+(\.\w+)*$/';
| RFC 5322 合法 | 本文正則 | filter_var | 備註 | |
|---|---|---|---|---|
| user@example.com | ✓ | ✓ | ✓ | 標準格式 |
| user.name@domain.com | ✓ | ✓ | ✓ | 本地部含點號 |
| user+tag@domain.com | ✓ | ✗ | ✓ | Plus addressing (Gmail 支援) |
| "user name"@domain.com | ✓ | ✗ | ✓ | 雙引號包含空格 |
| user@[IPv6:2001:db8::1] | ✓ | ✗ | ✗ | IP 字面位址 |
| user@sub.domain.co.uk | ✓ | ✓ | ✓ | 多級域名 |
| user@domain.c | ✗ | ✗ | ✗ | 頂級域至少 2 字元 |
filter_var($email, FILTER_VALIDATE_EMAIL):內建支援完整 RFC 5322,無需維護複雜正則<input type="email"> 瀏覽器原生支援$disposable_domains = [
'10minutemail.com', 'guerrillamail.com', 'mailinator.com',
'tempmail.com', 'trashmail.com', 'yopmail.com'
];
function isDisposableEmail($email) {
global $disposable_domains;
$domain = strtolower(substr(strrchr($email, '@'), 1));
return in_array($domain, $disposable_domains);
}