分享二個實用正則
前言
正則表達式(Regular Expression,簡稱regex或regexp)是一種用于匹配和操作文本的強大工具。它由一系列字符和特殊字符(稱為元字符)組成,用于描述要匹配的文本模式。正則表達式可以在文本中查找、替換、提取和驗證特定的模式
最近看到二個我覺得很實用的正則使用方式,特寫文章記錄下來
數字千分位處理
功能:把數字1234567轉為1,234,567
代碼如下:
/**
* 數字千分位處理(對于非數字返回null)
* @param {number} value - 需要進行千分位格式化的數字
* @returns {string | null} - 千分位格式化后的結果
*/
function formatNumber(value) {
if (isNaN(value)) return null;
// 先將數字轉為字符串,并分割整數和小數部分
const [integerPart, decimalPart] = `${value}`.split('.');
// 只對整數部分添加千位分隔符
const formattedInteger = integerPart.replace(/(\\d)(?=(\\d\\d\\d)+(?!\\d))/g, "$1,");
// 如果有小數部分,重新組合
return decimalPart ? `${formattedInteger}.${decimalPart}` : formattedInteger;
}
正則表達式分解:
- (\d) - 捕獲組1:匹配任意一個數字
- (?=...) - 正向預查:匹配后面跟特定內容的位置
- (\d\d\d)+ - 捕獲組2:匹配3個數字,可以重復一次或多次
- (?!\d) - 負向預查:確保后面沒有其他數字
- /g - 全局匹配標志
工作原理:
讓我們用一個具體例子來說明,比如數字 "1234567":
分析正則匹配過程:
a. 第一次匹配:
* (\\d) 匹配到 "1"
* (?=(\\d\\d\\d)+(?!\\d)) 向前預查:
發現后面有 "234567"
符合 (\\d\\d\\d)+ 模式("234" 和 "567")
最后一位后面沒有數字((?!\\d))
匹配成功,替換為 "1,"
b. 失敗的匹配:
* 逗號后繼續
* (\\d) 匹配到 "2"
* 向前預查發現后面是 "34567"
* 符合 (\\d\\d\\d)+ 模式("345")
* 但后面還有 "67",不符合 (?!\\d)
* 匹配失敗
c. 成功的匹配:
* 繼續向前
* (\\d) 匹配到 "4"
* 向前預查發現后面是 "567"
* 符合 (\\d\\d\\d)+ 模式
* 最后一位后面沒有數字
* 匹配成功,替換為 "4,"
* 最終結果:
* 原始數字 "1234567" → "1,234,567"
依次把所有數字匹配完成
限制條件:
不處理小數部分
不處理負號
只在正確的千分位位置添加逗號
不會在數字開頭添加逗號
強密碼驗證
在做用戶登錄/注冊的時候,有的要求用戶的賬號密碼必須是強密碼,如必須是有大小寫字母數字加特殊字符
代碼如下:
/**
* 驗證密碼(所有驗證邏輯整合到單個正則中)
* @param {string} password - 需要驗證的密碼
* @param {number} [minLength=8] - 最小長度
* @param {number} [maxLength=32] - 最大長度
* @param {string} [allowedSpecials='!@#$%^&*()'] - 允許的特殊字符集合
* @returns {Object} - 驗證結果和錯誤信息
*/
function validatePassword(
password,
minLength = 8,
maxLength = 32,
allowedSpecials = '!@#$%^&*()'
) {
const errors = [];
// 特殊字符轉義(處理正則元字符)
const escapedSpecials = allowedSpecials.replace(/[\\\\^$.*+?()[\\]{}|]/g, '\\\\$&');
// 整合長度驗證的正則表達式
// 核心:在原正則基礎上添加長度限制 {minLength, maxLength}
const regex = new RegExp(
`^(?=.*[a-z])(?=.*[A-Z])(?=.*\\\\d)(?=.*[${escapedSpecials}]).{${minLength},${maxLength}}$`
);
if (!regex.test(password)) {
// 長度錯誤檢查
if (password.length < minLength) {
errors.push(`密碼長度不能少于${minLength}個字符`);
}
if (password.length > maxLength) {
errors.push(`密碼長度不能超過${maxLength}個字符`);
}
// 字符類型錯誤檢查
if (!/[a-z]/.test(password)) errors.push("必須包含至少一個小寫字母");
if (!/[A-Z]/.test(password)) errors.push("必須包含至少一個大寫字母");
if (!/\\d/.test(password)) errors.push("必須包含至少一個數字");
if (!new RegExp(`[${escapedSpecials}]`).test(password)) {
errors.push(`必須包含至少一個特殊字符(允許的字符:${allowedSpecials})`);
}
}
return {
isValid: errors.length === 0,
errors: errors
};
}
-
特殊字符轉義,處理 allowedSpecials
作用:將 allowedSpecials 中包含的「正則元字符」(如 *、(、$ 等)轉義為普通字符(如 * → *),避免破壞正則語法。
例如:若 allowedSpecials 是 '$()',轉義后變為 '$()'(字符串中顯示為 $*())。
const escapedSpecials = allowedSpecials.replace(/[\\\\^$.*+?()[\\]{}|]/g, '\\\\$&');
-
核心正則表達式詳解
這里用 new RegExp() 動態生成正則,將轉義后的特殊字符(escapedSpecials)和密碼長度驗證嵌入正則中。
假設 allowedSpecials 是默認的 '!@#$%^&*()',轉義后 escapedSpecials 為 '!@#$%^&*()',假設minLength為8,maxLength為32,則生成的正則字符串為:^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[!@#\\$%\\^&\\*\\(\\)]).{8,32}$這是一個包含4 個正向預查的正則,用于強制要求密碼同時滿足多種字符類型。我們逐個拆解:
正則部分 含義解釋 ^匹配字符串的開始位置(確保從開頭就檢查,避免只匹配部分字符串)。 (?=.*[a-z])正向預查:確保字符串中至少有一個小寫字母( [a-z])。
-.*表示任意字符(除換行)重復任意次(包括 0 次)。
- 整體含義:“從當前位置開始,后面存在至少一個小寫字母”。(?=.*[A-Z])正向預查:確保字符串中至少有一個大寫字母( [A-Z])。(?=.*\\d)正向預查:確保字符串中至少有一個數字( \\d等價于[0-9])。(?=.*[!@#$%^&*()])正向預查:確保字符串中至少有一個允許的特殊字符(即 allowedSpecials中指定的字符)。.{8,32}表示 “匹配任意字符(除換行),且長度在 minLength 到 maxLength 之間 $匹配字符串的結束位置(確保檢查到字符串末尾,避免遺漏)。
小結
正則又叫火星文,它的用法千千萬,個人知識有限,如果你有一些更好的正則好用的方式,歡迎留言分享,一起學習一起進步

浙公網安備 33010602011771號