本人是一枚前端小嘍囉,在工作中常用到正則表達式,於是抽空系統學習了一下正則表達式基礎。今天筆者就把所學內容分享給大家,筆者將首先展示一些小例子,帶領大家逐步理解正則表達式,然後在這些小例子的基礎上,實現一個可以匹配郵箱地址的正則(本文所列案例皆可在瀏覽器控制枱執行)。
直奔主題
1. 最簡單的正則:匹配特定字符串
let reg = new RegExp("a")
reg.test("a")
//結果為true
reg.test("b")
//結果為false
這個例子簡單直接,我們使用RegExp構造器構造一個正則表達式對象,這個正則的目標就是匹配字符串中"a",包含返回true,不包含返回false。
2. 正則表達式中的匹配模式
聲明正則表達式對象時,可以給正則表表達式傳遞第二個參數即:匹配模式。匹配模式有三個類型:
| 修飾符 | 描述 |
|---|---|
| i | 不區分大小寫匹配 |
| g | 全局匹配 |
| m | 多行匹配。 |
這裏,我們創建一個不區分大小寫的正則表達式:
//注意,匹配模式的參數也是String類型
let reg = new RegExp("a","i")
reg.test("A")
//結果為true
reg.test("b")
//結果為false
當然,在JavaScript中也可以通過字面量方式創建正則表達式,這種方式創建的正則表達式與採用RegExp構造的對象是一樣的,類型同樣是Object。
//構造器方式
let reg = new RegExp("a","i")
//字面量方式
let reg = /a/i
3. 檢測一個字符串中是否有"a"或"b"(大小寫不敏感)
let reg = /a|b/i
reg.test("a")
//true
reg.test("b")
//true
reg.test("riku")
//false
定義一個正則表達式時,如果將某些字符放到[]內,則[]內的字符是或的關係,即只要包含任意一個即為true。
4. 匹配任意字母
let reg = /[A-z]/
reg.test("douban")
//true
reg.test("taoBao")
//true
reg.test("123")
//false
這個正則用來匹配大寫A到小寫z之間的所有字符,因為大寫字母的ASCII碼比小寫字母的ASCII碼要小,所以A-z表示所有字母,再放到[]中表示對任意大小寫字母的匹配,所以這裏我們不再需要名稱為i的修飾符來表示不區分大小寫。
5. 匹配abc、bbc、cbc中任意一個字符串
let reg = /[abc]bc/
reg.test("abc")
//true
reg.test("bbc")
//true
reg.test("cbc")
//true
reg.test("1bc")
//false
6. 匹配abc之外的字符串
let reg = /[^abc]/
reg.test("ab")
//false
reg.test("abx")
//true 因為包含了除abc之外的字符x
let reg = /[^0-9]/
//該正則可以匹配任何非數字的字符,比較常用!
在方括號之前加上^符號,表示匹配任意不在方括號之間的字符。
與正則相關的字符串方法
與字符串相關的正則方法一共有四個,如下表所列:
| 方法名 | 具體作用 |
|---|---|
| search | 檢索與正則表達式相匹配的值 |
| match | 找到一個或多個正則表達式的匹配 |
| replace | 替換與正則表達式匹配的子串 |
| split | 把字符串分割為字符串數組 |
我們先從split説起:
1. 根據任意數字拆分字符串
let str = "a1b2c3d4e5f6g"
let arr = str.split(/[0-9]/)
console.log(arr)
// 結果為["a", "b", "c", "d", "e", "f", "g"]
字符串的split方法可以根據指定規則拆分字符串,這裏我們需要注意的是,即使沒有執行全局匹配,split依舊會對整個字符串執行拆分操作。
字符串的search方法可以搜索字符串中是否含有指定內容,類似於str.indexOf()方法,如果搜索到則返回第一個匹配到的索引,否則返回-1,對於search,即使指定了全局匹配,返回的也只有第一個匹配到的結果,即search不能全局匹配。
2. 搜索一個字符串中的user1,user2,user3
let str = "userlist :user1 ,user2,user3"
console.log(str.search(/user[123]/))
// 結果為10即第一個匹配到的user1的索引值
字符串的match方法,可以根據正則表達式的匹配結果,從一個字符串中提取一個字符串數組。
默認情況下,match方法只會匹配第一個結果,找到後便停止繼續向後檢索
如果想讓match方法進行全局匹配,我們只需加上之前講的/g修飾符,也可以添加/i修飾符執行大小寫不敏感匹配。
3. 提取一個字符串中所有的數字
let str="1a2b3c4d5e6f"
let arr = str.match(/[0-9]/g)
//arr的打印結果為["1", "2", "3", "4", "5", "6"]
str.replace()可以將字符串中匹配到的內容替換為新的內容。replace包含兩個參數:
1、被替換的內容(可以是正則表達式)
2、新的內容,可以是一個字符串或者是回調函數,回調函數可以操作匹配到的每一項的內容。
4. 將字符串中小寫單詞首字母改成大寫
let str = "abc bbc cbc"
let reg = /\b\w+\b/g
let result = str.replace(reg, (word) => {
return word.substring(0, 1).toLocaleUpperCase() + word.substring(1)
})
console.log(result);
在正則表達式中,可以通過量詞設定字符出現的次數,但量詞只對他前面那一個字符生效,如果我們希望量詞對前面幾個字符生效,我們可以用括號包起來,如:(ab){3,5} 表示ab出現3-5次,如果省略5,則表示出現3次貨3次以上。
常用量詞如下表所示:
| 量詞 | 具體作用 |
|---|---|
| {n} | 檢索與正則表達式相匹配的值 |
| {m,n} | 找到一個或多個正則表達式的匹配 |
| {m,} | 替換與正則表達式匹配的子串 |
| + | 至少出現一次,相當於{1,} |
| * | 0次或1次或多次,相當於{0,} |
| ? | 0次或一次,相當於{0,1} |
5. 判斷一個字符串是否為合法的手機號
let phoneReg = /^1[3-9][0-9]{9}$/
phoengReg.test('13123456789')
//結果為true,我們這裏的驗證規則時:以1開頭,第二位是3-9之間任意數字,
//剩下9位是任意數字,因此總位數為11位
//開始的^符號表示開始,最後的$符號表示字符串結束。
6. 去除一個字符串開頭和結尾的所有空格
let str = " hello world "
let strReg = /^\s*|\s*$/g
str = str.replace(strReg,"")
//執行結果為:"hello world",這裏需要指定全局匹配,否則只會匹配前面的空格。
這裏,筆者還想介紹一下元字符的概念,就是我們上面一個案例中用到的\s他表示的是任意空格,在正則表達式中常用的元字符如下表所示:
| 元字符 | 具體含義 |
|---|---|
| \w | 任意字母、數字、下劃線[A-z0-9_] |
| \W | 除了字母、數字、下劃線[^A-z0-9_] |
| \d | 任意數字[0-9] |
| \D | 除了數字[^0-9] |
| \s | 空格 |
| \S | 除了空格 |
| \b | 單詞邊界 |
| \B | 除了單詞邊界 |
匹配郵箱的正則
正常來説,一個郵箱地址由一下幾個部分構成
我們以test.zhou@test.com.cn為例,將郵箱拆分成以下幾個部分:
①test ②.zhou ③@ ④test ⑤.com ⑥.cn對應的匹配規則如下:任意長度字符串:
\w{3,}
"."或者"_"+任意長度字符串(可選):
((\.|\_)\w+)*
"@"符號
@
任意長度字母數字:
[A-z0-9]+
"."+長度為2-6的字符串:
\.[A-z]{2-6}
"."+長度為2-5的字符串(可選):
\.[A-z]{2-5}
最後我們把剛才分析的6個部分整合到一起,就得到了我們想要的對郵箱進行校驗的正則表達式:
let emailReg = /\w{3,}((\.|\_)\w+)*@[A-z0-9]+\.[A-z]{2,6}(\.[A-z]{2,5})*/
emailReg.test("test@test.com.cn") //true
emailReg.test("test.liu@test.test") //true
總結
本文首先從最簡單的字符串匹配開始,介紹瞭如何在JavaScript中使用正則表達式匹配目標對象,然後介紹了正則表達式的匹配模式,接着又介紹了字符串與正則結合使用的四個方法:search、match、replace、split,最後又綜合運用正則表達式基礎知識,實現了一個郵箱的正則匹配表達式。
本文旨在幫助開發同學們入門正則表達式,幫助大家在工作中把正則用起來,為逐步深入學習正則表達式做好鋪墊。