郵箱驗證是 Web 表單高頻需求。本文提供基於 PCRE 的實用正則,演示如何驗證合法性並提取用戶名、域名部分,同時推薦使用 PHP 內建 filter_var 獲得更健壯的驗證。
<?php
header('Content-Type: text/html; charset=UTF-8');
$reply = '';
if (isset($_POST['email_address'])) {
$email = trim($_POST['email_address']);
// 實用正則:本地部分允許字母數字._%+-,域名標準格式
$pattern = '/^([a-zA-Z0-9._%+-]+)@([a-zA-Z0-9.-]+\.[a-zA-Z]{2,})$/i';
if (preg_match($pattern, $email, $matches)) {
$reply = "郵箱格式合法<br><br>\n";
$reply .= "用戶名:{$matches[1]}<br>\n";
$reply .= "域名:{$matches[2]}<br>\n";
} else {
$reply = "郵箱格式不合法";
}
}
?>
<!DOCTYPE html>
<html>
<head><title>郵箱驗證演示</title></head>
<body>
<h1>電子郵件地址驗證程序</h1>
<form method="post">
請輸入郵箱:<input name="email_address" type="text" size="40" /><br><br>
<input type="submit" value="驗證" />
</form>
<?php echo $reply; ?>
</body>
</html>
| 片段 | 含義 |
|---|---|
^ | 字符串開始 |
([a-zA-Z0-9._%+-]+) | 捕獲組 1:用戶名,允許字母、數字、點、下劃線、百分號、加號、減號,至少一個 |
@ | 字面 @ 符號 |
([a-zA-Z0-9.-]+\.[a-zA-Z]{2,}) | 捕獲組 2:域名,子域名允許字母數字點減號,頂級域至少 2 字母 |
$ | 字符串結束 |
i | 大小寫不敏感修飾符 |
<?php
function is_valid_email($email) {
// 基礎驗證
if (filter_var($email, FILTER_VALIDATE_EMAIL) === false) {
return false;
}
// 可選:長度限制 (RFC 5321: 本地部分 ≤64,域名 ≤255,總長 ≤254)
if (strlen($email) > 254) return false;
// 可選:禁止連續雙點、首尾點等邊界情況
if (preg_match('/\.\.|^\\.|\\.$|@\\./', $email)) return false;
return true;
}
// 測試
var_dump(is_valid_email('test@example.com')); // true
var_dump(is_valid_email('user.name+tag@sub.domain.cn')); // true
var_dump(is_valid_email('invalid@.com')); // false
var_dump(is_valid_email('no-at-sign.com')); // false
?>
對於中文域名郵箱 (如 用戶@例子.中國),需先轉換為 ASCII (Punycode):
<?php
function validate_idn_email($email) {
if (filter_var($email, FILTER_VALIDATE_EMAIL)) return true; // 純 ASCII 通過
// 嘗試分割並轉換域名部分
if (preg_match('/^(.+)@(.+)$/u', $email, $m)) {
$local = $m[1];
$domain = $m[2];
// 域名轉 Punycode
$domainAscii = idn_to_ascii($domain, IDNA_NONTRANSITIONAL_TO_ASCII, INTL_IDNA_VARIANT_UTS46);
if ($domainAscii) {
return filter_var($local . '@' . $domainAscii, FILTER_VALIDATE_EMAIL) !== false;
}
}
return false;
}
?>
前提:安裝 intl 擴展 (pecl install intl 或 apt-get install php-intl)。
filter_var 覆蓋 99.9% 實際場景。type="email" 規則較寬鬆,服務端必須二次驗證。.*,關鍵位置加 + 而非 *。