經典正則 (PHP 4/5 早期常見)
ereg("^[_.0-9a-z-]+@([0-9a-z][0-9a-z-]+\.)+[a-z]{2,3}$", $email)
逐段解析
| 片段 | 含義 |
^ | 字串開頭 |
[_.0-9a-z-]+ | 使用者名:字母、數字、底線、點、連字號,至少一個 |
@ | 字面 @ 符號 |
([0-9a-z][0-9a-z-]+\.)+ | 域名標籤:字母/數字開頭,接字母/數字/連字號,以點結尾,至少一組 |
[a-z]{2,3} | 頂級域:2-3 個字母 (com, net, org, tw, jp...) |
$ | 字串結尾 |
此正則的缺陷
- 不支援長頂級域 (
.info, .museum, .technology 等)
- 不支援國際化域名 (IDN、中文域名)
- 不支援使用者名中的
+、% 等合法字元
ereg/eregi 自 **PHP 5.3 棄用、PHP 7.0 移除**
- 大小寫不敏感 (
eregi) 但域名實際不分大小寫
現代驗證方案
1. filter_var() 內建驗證 (PHP 5.2+)
$email = 'user@example.com';
if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
// 格式基本合法
}
// 選項:FILTER_FLAG_EMAIL_UNICODE (PHP 7.1+) 支援 Unicode
2. 正則改良版 (RFC 5322 簡化)
function isValidEmail(string $email): bool {
$pattern = '/^[a-zA-Z0-9.!#$%&\'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/';
return (bool)preg_match($pattern, $email);
}
3. 真正送驗證信 (唯一可靠方式)
function sendVerificationEmail(string $email, string $token): bool {
$link = "https://example.com/verify?token=$token";
$subject = '請驗證您的 Email';
$body = "點擊連結驗證: $link";
return mail($email, $subject, $body, "From: no-reply@example.com\r\nContent-Type: text/plain; charset=UTF-8");
}
前端 + 後端雙重驗證
<input type="email" name="email" required pattern="[^@\s]+@[^@\s]+\.[^@\s]+" />
// HTML5 內建驗證 (瀏覽器支援度高)
// 後端
if (!filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)) {
throw new InvalidArgumentException('Email 格式錯誤');
}
效能比較
| 方法 | 速度 | 準確度 | 建議 |
| filter_var() | 極快 (C 實作) | 高 (RFC 兼容) | 首選 |
| preg_match 正則 | 快 | 視正則品質 | 需自訂規則時 |
| 發送驗證信 | 慢 (網路 IO) | 100% (實際存在) | 關鍵業務必做 |