javascript正規表示式 | 知識梳理

VimMing發表於2020-02-16

寫這篇文章的原因有兩點,第一是自我的知識整理和分享,第二是在工作中偶爾能要使用正則,當要用的時候方便知識查詢,正則裡面的元字元一大堆,上網搜有時候不知道去表述或Google關鍵字。

如何建立正則

字面量方式

這種方法最方便簡單

// /pattern/flags
let reg = /\d/g
console.log(reg) 
複製程式碼

建構函式方式

這種方法比字面量麻煩,它的pattern為字串,比起字面量的方式的優勢在於可以動態的拼接

// 注意的一點是字面量裡面寫一個\, 這裡要寫兩個\\
let reg = new RegExp('\\d', 'g')
console.log(reg)
複製程式碼

js裡與正則相關的函式

函式 引數 返回
exec(arg1); arg1: 字串 Array
test(arg1); arg1: 字串 Boolean
replace(arg1, arg2) arg1: 正則 或者 字串 , arg2: 字串 或 回撥函式 String

下面是這三個函式使用的簡單例子

let reg = /\d/g
console.log(reg.test('123abc'))
console.log(reg.exec('123tgb'))
console.log('123gb'.replace(reg, 'a'))
複製程式碼

正則裡面的括號

大括號 {}

正規表示式裡面的大括號裡面的內容為數字,表示前面的字元要重複多少次,簡單的說{}用於設定匹配的長度。 看下面的例子:

// 匹配字元中b重複2到3次x重複2到3次
let reg = /b{2,3}x{2,3}/
console.log(reg.test('bbxx')) // true
console.log(reg.test('bbx')) // flase
// 字串中b的重複次數必須大於等於2才能被匹配
let reg1 = /b{2,}/
複製程式碼

中括號 []

中括號[]裡的內容組成一個字元範圍,只要目標字串出現在其中就可以了,看下面的例子:

let reg = /b[143hg]b/ 
reg.test('b3b') // true, 3存在於143hg
reg.test('b143hgb') // false, 匹配模式為bxb x=1 或者 x = 3, x = 4, x = h, x=g 
複製程式碼

小括號 ()

小括號()常用於正則分組, 如下圖:

javascript正規表示式 | 知識梳理
javascript約定組名的方式如上圖,下面看下例子加深你對捕獲組的理解:

let reg = /a(\d(\w))/
// 用$&(可以理解為0組),替換reg匹配的內容, 列印的內容應該不變
console.log("fa5baf".replace(reg, '$&')) // fa5baf
// 用$1(第一組),替換reg匹配的內容
console.log("fa5baf".replace(reg, '$1')) // f5baf
// 用$1(第一組),替換reg匹配的內容
console.log("fa5baf".replace(reg, '$2')) // fbaf
複製程式碼

小括號搭配|也能當中括號用,看下面的例子:

let reg = /a[143hg]b/
let reg1 = /a(1|4|3|h|g)b/
// reg 和 reg1的效果一樣。() 搭配 | 組成匹配集合
複製程式碼

元字元

正規表示式語言由兩種基本字元型別組成:原義(正常)文字字元和元字元。元字元使正規表示式具有處理能力。所謂元字元就是指那些在正規表示式中具有特殊意義的專用字元,可以用來規定其前導字元(即位於元字元前面的字元)在目標物件中的出現模式。

常用

程式碼 解釋
. 匹配除換行符(\n, \r)以外的任意字元
\w 匹配字母或數字或下劃線
\W 匹配任意不是字母,數字,下劃線,漢字的字元
\s 匹配任意的空白符
\S 匹配任意不是空白符的字元
\d 匹配數字
\D 匹配任意非數字的字元
\b 匹配不是\w的開始的位置
\B 匹配是\w開頭的位置
^ 匹配字串的開始
$ 匹配字串的結束
| 匹配組裡表示或

重複

程式碼/語法 說明
* 重複零次或更多次
+ 重複一次或更多次
? 重複零次或一次
{n} 重複n次
{n,} 重複n次或更多次
{n,m} 重複n到m次

貪婪

程式碼/語法 說明
*? 重複任意次,但儘可能少重複
+? 重複1次或更多次,但儘可能少重複
?? 重複0次或1次,但儘可能少重複
{n,m}? 重複n到m次,但儘可能少重複
{n,}? 重複n次以上,但儘可能少重複

斷言

在使用正規表示式時,有時我們需要捕獲的內容前後必須是特定內容,但又不捕獲這些特定內容的時候

先行斷言

程式碼/語法 說明 例子
(?=exp) 匹配exp前面的位置 正則: /\b\w+(?=ing\b)/g , 測試字元: I'm singing while you're dancing. 匹配: sing , danc
(?!exp) 匹配後面跟的不是exp的位置 正則: /\d+(?!%)/ ,測試字元: 'that’s all 44 of them' 匹配: 44

後行斷言

程式碼/語法 說明
(?<=exp) 匹配exp後面的位置
(?<!exp) 匹配前面不是exp的位置

超級實用的例子

如果下面正規表示式理解起來遇到困難,你可以複製它,去這個網站,這個網站可以根據正則生成圖譜regexper

金額格式化
// \B可以理解為 '', 且''前面必須為\w 即 [0-9a-zA-Z]
// (?=) 先行斷言
let reg = /\B(?=(\d{3})+(?!\d))/g
// console.log("123456789".replace(reg, ',')) // '' => ',' 123,456,789
複製程式碼
郵箱
let reg = /^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/
複製程式碼
漢字
let reg = /^[\u4e00-\u9fa5]{0,}$/
複製程式碼
ip
// (?:) 非捕獲型
let reg = /((?:(?:25[0-5]|2[0-4]\d|[01]?\d?\d)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d?\d))/
複製程式碼
域名
let reg = /^(https?:\/\/)?([\w]([\w\-]{0,61}[\w])?\.)+[\w]{2,6}(\/)?$/
複製程式碼

大家可以在評論區說下你常用正規表示式...

相關文章