正則表達式是文本處理的「瑞士軍刀」。本文匯總 Web 開發最高頻的 10 類正則模式,提供 **PHP (PCRE)** 與 **JavaScript** 雙語言語法對照、驗證代碼片段、邊界測試用例、性能優化提示,作為開發隨手查閱的速查手冊。
| # | 場景 | PHP (PCRE) | JavaScript | 說明/邊界 |
|---|---|---|---|---|
| 1 | 正整數 | /^[1-9]\d*$/ | /^[0-9]*[1-9][0-9]*$/ | 不含 0;JS 需排除前導 0 |
| 2 | 非負整數 (含 0) | /^\d+$/ | /^\d+$/ | 等價 /^[0-9]+$/ |
| 3 | 中文字符 | /^[\x{4e00}-\x{9fa5}]+$/u | /^[\u4e00-\u9fa5]+$/ | PHP 需 u 修飾符;基本區 |
| 4 | /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/ | 同左 | 簡化版;RFC 5322 完整版極複雜,通常前端 HTML5 type=email + 後端 filter_var($email, FILTER_VALIDATE_EMAIL) | |
| 5 | URL | /((f|ht){1}(tp|tps):\/\/)[-a-zA-Z0-9@:%_\+.~#?&\/\/=]+/ | /^(f|ht){1}(tp|tps):\/\/([\w-]+\.)+[\w-]+(\/[\w-.\/?%&=]*)?$/ | 建議用 filter_var($url, FILTER_VALIDATE_URL) 或專用庫 |
| 6 | 用戶名 (字母開頭, 5-16位, 字母數字下劃線) | /^[a-zA-Z][a-zA-Z0-9_]{4,15}$/ | 同左 | 長度含首字母 |
| 7 | 通用名稱 (中英數下劃線) | /^[\x{4e00}-\x{9fa5}A-Za-z0-9_]+$/u | /^[\u4e00-\u9fa5A-Za-z0-9_]+$/ | 姓名、標簽、分類名等 |
| 8 | 中國郵政編碼 | /^[1-9]\d{5}$/ | 同左 | 6 位,首位非 0 |
| 9 | IPv4 地址 | /\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b/ | 同左 | 精確匹配 0-255 四段 |
| 10 | 中國大陸身份證 (18位) | /^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}(\d|x|X)$/ | 同左 | 含地址碼、出生日期、順序碼、校驗碼;不含校驗算法,需額外驗證 |
<?php
function validate($pattern, $subject, $flags = 0) {
return (bool)preg_match($pattern, $subject, $matches, $flags);
}
// 使用
$patterns = [
'mobile' => '/^1[3-9]\d{9}$/', // 手機號
'idcard' => '/^[1-9]\d{5}(19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[\dXx]$/',
'password' => '/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[~!@#$%^&*]).{8,}$/', // 強密碼
'hexcolor' => '/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/',
];
$input = '13800138000';
if (validate($patterns['mobile'], $input)) {
echo "手機號格式正確";
}
// 提取所有匹配
preg_match_all('/\b\d{4}-\d{2}-\d{2}\b/', $text, $dates); // 提取 YYYY-MM-DD
// 替換
$clean = preg_replace('/\s+/', ' ', $dirty); // 多空白合併為單空格
$masked = preg_replace_callback('/\d{4}(\d{4})/', fn($m) => '****' . $m[1], $card); // 脫敏
?>
<script>
const patterns = {
mobile: /^1[3-9]\d{9}$/,
idcard: /^[1-9]\d{5}(19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[\dXx]$/,
password: /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[~!@#$%^&*]).{8,}$/,
url: /^https?:\/\/([\w-]+\.)+[\w-]+(\/[\w-.\/?%&=]*)?$/,
};
function validate(pattern, str) {
return pattern.test(str);
}
// 使用
if (validate(patterns.mobile, '13800138000')) {
console.log('手機號正確');
}
// 提取
const dates = text.match(/\b\d{4}-\d{2}-\d{2}\b/g);
// 替換
const clean = dirty.replace(/\s+/g, ' ');
const masked = card.replace(/\d{4}(\d{4})/, '****$1');
// 表單提交攔截
form.addEventListener('submit', e => {
if (!validate(patterns.password, pwd.value)) {
e.preventDefault();
alert('密碼需含大小寫、數字、特殊字符,至少 8 位');
}
});
</script>
| 場景 | 正則 (PHP/JS 通用) | 示例匹配 |
|---|---|---|
| 手機號 (中國大陸) | /^1[3-9]\d{9}$/ | 13800138000 |
| 強密碼 (大小寫+數字+特殊符號, 8+) | /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[~!@#$%^&*]).{8,}$/ | Abc123!@ |
| 十六進制顏色 | /^#([0-9a-f]{3}|[0-9a-f]{6})$/i | #fff, #1a2b3c |
| 日期 YYYY-MM-DD | /^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$/ | 2024-12-31 |
| 時間 HH:MM:SS (24h) | /^([01]\d|2[0-3]):([0-5]\d):([0-5]\d)$/ | 23:59:59 |
| 銀行卡號 (Luhn 需另驗) | /^\d{15,19}$/ | 6225880123456789 |
| 車牌號 (新能源+普通) | /^([京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-HJ-NP-Z][A-HJ-NP-Z0-9]{4,5}[DF])|([京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-HJ-NP-Z][A-HJ-NP-Z0-9]{5})$/ | 京A12345, 粤B6666D |
| 中文標點符號 | /[,。!?、;:「」『』()【】《》〈〉]/ | ,。!? |
| HTML 標簽 (簡易) | /<[^>]+>/ | <div>, <img src="..."> |
(.*)、(.+) 貪婪匹配,改用 (.*?) 非貪婪或具體字符集 ([^"]*)。^ $ 定位開頭結尾,不要讓引擎掃描整字符串。$regex = '/pattern/';JS 模塊級常量定義,避免循環中重複創建 RegExp 對象。u (UTF-8)、i (忽略大小寫)、m (多行模式 ^$ 匹配行首尾)、s (單行模式 . 匹配換行)。正則表達式威力巨大,但「寫時易讀,維護難讀」。**能用內置函數/庫解決(如 filter_var, DateTime, URLSearchParams)就不用正則**;必須用時,遵循:錨點優先、具體字符集、非貪婪、預編譯、註釋文檔、單元測試覆蓋邊界值。收藏本表,下次驗證手機號、提取日期、脫敏手機號不再現場造輪子。