什麼是正則表達式
- 正則表達式 Regular Expression (構造函數 RegExp)
- 用於字符串匹配規則
- 要麼匹配字符,要麼匹配位置
如何新建正則表達式
- 字面量 /[ab]/gim
const reg = /[\w\*\.]{2}/;
console.log(reg.test('**')); //true
- 構造函數 new RegExp(
[ab${c}]\\d
,'gim'); 注意:用構造函數內部表示字符串,當使用\w,\d 等特殊轉譯字符時候,\默認是當作轉譯字符串來處理的,所以要多加一個\ 再進行轉譯。 當正則創建要用到變量時候,必須使用構造函數形式創建!
const reg = new RegExp('[\\w\*\.]{2}','gim');
// 在正則中插入變量,只能使用構造函數方式新建
const value = '永遠的43';
const reg = new RegExp(`^${value}號$`);
const reg.test('永遠的43號'); // true
正則字符
-
元字符 ( ) [ ] +|{ }. * ? ^ $
元字符表示在正則中有特殊意義,如果需要使用到元字符的字符串匹配,需要使用轉譯字符。 -
特殊字符(\w, \W, \d, \D, \s, \S等)
-
\w 單詞字符[a-zA-Z_0-9]
-
\W 非單詞字符[^a-zA-Z_0-9]
-
\d 數字字符[0-9]
-
\D 非數字字符[^0-9]
-
\s 空格字符(空格,製表符等)
-
\S 非空格字符
一 匹配位置
位置字符:
^ $ \b \B (?=P) (?!p) (?<=p) (?<!p)
- ^ 表示字符串第一個字符之前位置
- $表示字符串最後一個字符之後的位置
// 在字符串開頭位置添加一個字符¥,末尾加一個.00 字符
const str = '5600';
const money = str.replace(/^/,'¥').replace(/$/,'.00');
console.log(money); // ¥5600.00
-
\b 表示單詞字符\w與非單詞字符\W之間的位置,也包括\w字符與^和$之間的位置(與\w 一起使用,表示單詞邊界)
-
\B 表示單詞字符之間的位置,非單詞字符與^ 和|之間的位置,非單詞字符之間的位置(與\w 一起使用,表示單詞內部位置)
-
(?=P) 表示 P之前的位置;(?!P)表示除開P之前位置的所有位置
-
(?<=P)表示 P之後的位置;(?<!P)表示除開P之後的位置的所有位置
// 格式化金額,例如 500000 -> 500,000;-500000->-500,000;
// 分析:加的,字符不能在頭部,也不能在-後面
// 步驟一
const reg = /(?=(\d{3})+$)/g;
const str = '500000';
const money = str.replace(reg,','); // ,500,000;
// 步驟二:處理,不能出現在字符串首部
const reg = /(?!^)(?=(\d{3})+$)/g;
const str = '500000';
const money = str.replace(reg,','); // 500,000;
// 貌似滿足要求了,bug -500000測試發現...
const str = '-500000';
const money = str.replace(reg,','); // -,500,000;
// 步驟三處理不能在-號後
const reg = /(?!^)(?<!-)(?=(\d{3})+$)/;
const str = '-500000';
const money = str.replace(reg,','); // -500,000;
// okay! 貌似功能確實了,但是 太過複雜了,有沒有簡單點的方法呢
// 優化: 利用\B,\b
const reg = /\B(?=(\d{3})+\b)/; // 大功告成
二 匹配字符
量詞
量詞 | 次數 | 標準寫法 |
---|---|---|
* | 大於等於0次 | {0,} |
+ | 大於等於1次 | {1,} |
? | 0次或者1次 | {0,1} |
5次 | 精準匹配5次 | {5} |
貪婪模式 和 惰性模式
-
貪婪模式:一次匹配儘量匹配量詞最多,直到匹配不下,纔算一次匹配結束。/g 全局模式,會從上次匹配字符之後繼續進行匹配。 默認的量詞模式就是貪婪模式。
-
惰性模式:只匹配量詞最少情況,也就是一旦條件滿足就結束本輪匹配,/g模式會自動從已經匹配的字符之後開始下一輪匹配。
如何開啓惰性模式,在 量詞後面加 ?, 比如 \d[2,4]?
分支選擇模式默認爲惰性模式 (a|b|c)當匹配到了分支a,就不會再去匹配分支b或者c
惰性模式有什麼用?
例如: /a.*?b/g 匹配以a開頭,以b結尾 ,中間內容最少 的字符串
const a = 'abcdacb'
const reg1 = /a.*b/g
const reg2 = /a.*?b/g
console.log(a.match(reg1)); //['abcdacb']
console.log(a.match(reg2)); //['ab', 'acb']
分組匹配()
非捕獲括號(?: )
const phone = '18582556244';
const reg = /(\d{3})(\d{4})(\d{4})/;
const formatedphone = phone.replace(reg,(str,$1,$2,$3)=>{
return `${$1}-${$2}-${$3}`
}); // '185-8255-6244'
反向引用
通常在分支模式中,表示後續的匹配與上次匹配上的分支保持一致,使用\1,\2表示從左到右第一個括號匹配的內容
匹配模式 gim
- g 全局匹配
- i 忽略大小寫
- m 多行模式
使用正則方式
- 正則的方法
test 驗證 字符串是否滿足改正則表達式,返回ture/false
- 字符串的方法
replace,根據正則匹配特定的字符串進行替換,第二個參數可以是函數(在括號分組中有用)
match,返回滿足正則表達式的數組 (/g模式和非/g模式返回的值不同)
search,搜索返回滿足正則表達式的字符串在 原字符串中的起始位置
split,根據正則進行字符串拆分成數組
正則小練習
- 用正則實現str.trim()功能
- 講金幣轉化爲 ¥1,223,234.98 格式,截取保留兩位小數
- 將transform_new_data 轉化爲小駝峯命名
- 驗證密碼(8到12位,數字,小寫字母,大寫字母,且至少由兩種組合而成 )