今天咱們來說一下正則表達式的基本使用
i 執行對大小寫不敏感的匹配es6
let a = 'hEllo World' let reg = /hello/i console.log(reg.test(a)) // true let str = 'hello' let reg1 = /Hello/i console.log(reg1.test(str)) // true let str1 = 'hello' let reg2 = /Hello/ console.log(reg2.test(str1)) // false
上面的第一個例子字符串a帶有大寫英文,而咱們的匹配方式則爲所有小寫,咱們會獲得true,第二個例子str字符串所有爲小寫,而匹配方式則爲大小寫混合也是獲得true,第三個則是不使用修飾符i的,獲得爲false,因此i是對大小寫不敏感的正則表達式
g 執行全局匹配(查找全部匹配而非在找到第一個匹配後中止)數組
let a = 'hello hello hello hello' let reg = /hello/g console.log(a.replace(reg, '*')) // * * * * let a1 = 'hello Hello hello Hello' let reg1 = /Hello/g console.log(a1.replace(reg1, '*')) // hello * hello * let a2 = 'hello Hello hello Hello' let reg2 = /Hello/gi console.log(a2.replace(reg2, '*')) let a3 = 'hello _Hello hello Hello' let reg3 = /Hello/gi console.log(a3.replace(reg3, '*'))* _* * *
對於g全局的匹配,我對於它的理解就是能找到的均可以,只要符合的行,看上面的四個例子,最主要是看最後一個一個例子不論是不是一體只要符合你的規則就能夠函數
m 多行匹配學習
let a = 'hello\n hello hello hello' let reg = /hello/m console.log(a.replace(reg, '*')) // * hello hello hello let a1 = 'hello Hello\n hello Hello' let reg1 = /Hello/m console.log(a1.replace(reg1, '*')) // hello * hello hello let a1 = 'hello hello\n hello Hello' let reg1 = /Hello/m console.log(a1.replace(reg1, '*')) //hello hello hello *
經過上面的兩個例子,咱們已經知道m修飾符也算是查找全局的修飾符可是它匹配到一個就不會再進行匹配了測試
es6新增修飾y,又叫作粘連修飾符,和g修飾符相似也是全局匹配this
let str = "anta" let y = /a/y console.log(str.replace(y, "&")) // &nta console.log(str.replace(y, "&")) // anta let str = "aanta" let y = /a/y console.log(str.replace(y, "&")) //&anta console.log(str.replace(y, "&")) //a&nta console.log(str.replace(y, "&")) //aanta
上面第一個例子使用了y修飾符,第一次執行咱們匹配到了a替換成功,第二次的時候沒有值被匹配到,這是由於y修飾符匹配到一次後,會接着當前匹配到位置的下一個位置開始,因此在第一次替換的時候位置爲0,第二次匹配的時候位置則變爲了1,y修飾符是具備位置屬性的位置匹配,下面咱們就來看一下es5
let str = "aanta" let y = /a/y y.lastIndex = 4 console.log(str.replace(y, "&")) // aant& y.lastIndex = 1 console.log(str.replace(y, "&")) // a&nta
上面的兩個例子則是使用了位置,咱們能夠看到使用位置以後,會打亂y修飾符原有的粘連方式,會直接按照咱們規定的位置1匹配prototype
let str = "aanta" let y = /a/gy console.log(str.replace(y, "&")) // &&nta
上面的例子是g和y修飾符配合使用,會獲得咱們意想不到的結果,由於它會按照粘連規則檢驗code
RegExp.prototype.sticky 屬性檢驗是否設置了y修飾符
let y1 = /a/y console.log(y1.sticky) // true let y = /a/gy console.log(y.sticky) // true
RegExp.prototype.flags 屬性返回設置的修飾符
let y1 = /^a/y console.log(y1.flags) // y let y = /a/gy console.log(y.flags) // gy
es6 新增修飾符s 符號.匹配全部字符
let str = "aa\nnta" let reg = /a.n/s console.log(reg.test(str),reg.dotAll) // true true let str = "aa\nnta" let reg = /a.n/ console.log(reg.test(str),reg.dotAll) // false false
修飾符s匹配換行符n,咱們會獲得true,若是不用s修飾符的話會匹配不到的,上面的例子中都有檢測是否存在dotAll模式中,說白了主要就是看你有沒有修飾符s
[] 匹配中括號內規則的字符
let str = "hello world" let reg = /[a-z]/ console.log(reg.test(str)) // true let str = "hello world" let reg = /[a-h]/g console.log(str.replace(reg, '*')) // **llo worl* let str = "he1l3 wo4ld" let reg = /[0-9]/g console.log(str.replace(reg, '#')) // he#l# wo#ld
上面只是簡單的兩個例子只是簡單的測試下是否能夠匹配到中括號內的相關規則字符串
| 匹配多個規則至關於||或
let str = "he1l3 wo4ld" let reg = /[0-9|a-d]/g console.log(str.replace(reg, '#')) // he#l# wo#l# let str = "he1l3 wo4ldc@" let reg = /[0-9|a-d|c.]/sg console.log(str.replace(reg, '#')) // he#l# wo#l##@
上面第一個例子使用了g修飾符全局匹配0-9內的數字和a-d的字母替換,第二個例子使用了s和g的修飾符
正則表達式元字符
名字 | 使用描述 |
---|---|
/d | 匹配數字 |
D | 非數字字符 |
/s | 查找空白字符 |
S | 非空白字符 |
/b | 匹配單詞邊界 |
n | 匹配換行符 |
w | 單詞字符 |
W | 非單詞字符 |
/+ | 出現一到屢次 |
$ | 匹配結尾 |
\ | 轉義 |
^ | 匹配頭部出現的 |
t | 匹配製表符 |
0 | 查找null |
咱們按照順序寫幾個簡單的例子
匹配數字,只要是數字都能匹配到 let str = "hello 1235" let reg = /\d/g console.log(str.replace(reg, '*')) // hello **** 查找空白字符 let str = "hello 1235" let reg = /\s/g console.log(str.replace(reg, '*')) // hello*1235 匹配單詞邊界 let str = "hello 1235" let reg = /\b/g console.log(str.replace(reg, '*')) // *hello* *1235* 匹配換行符 let str = "hello\n123\n5" let reg = /\n/g console.log(str.replace(reg, '*')) // hello*123*5 /w匹配[a-zA-Z0-9_] let str = "Abv12_$" let reg = /\w/g console.log(str.replace(reg, '*')) // ******
匹配結尾的$
let str = "Abv12" let reg = /v$/g console.log(reg.exec(str)) // null let str = "Abv12v" let reg = /v$/g console.log(reg.exec(str)) // ["v", index: 5, input: "Abv12v", groups: undefined] ^匹配開頭的 let str = "Abv12v" let reg = /^v/g console.log(reg.exec(str)) // null let str = "vAbv12v" let reg = /v$/g console.log(reg.exec(str)) //["v", index: 0, input: "vAbv12v", groups: undefined] ^和$配合使用 let str1 = "abcd 1" let reg1 = /^[a-z]+\s+\d+$/i console.log(str1.replace(reg1, '*')) // *
匹配abcd 1,須要對應的規則分別是abcd ^[a-z] 空格s d數字$
{n} 匹配n個 {n,} 最少n個 {n, n} 最少匹配n個,最大匹配n個 ()捕獲性分組使用 let str = '2018-03-02' let reg = /^(\d{4})-(\d{2})-(\d{2})$/ console.log(str.replace(reg, "$1/$2/$3")) // 2018/03/02
上面的例子使用了()和{}配合使用,分紅了三個組,第一個組匹配四個數字,第二個和第三個匹配兩位數字,而後利用了^開始匹配的四位數字開始和$匹配兩位數字結束,將-替換/
()非捕獲性使用 非捕獲性分組經過將子表達式放在"?:"符號後,我理解的非捕獲性分組就是()有根沒有都同樣 let str = '2018-03-02' let reg = /^(?:\d{4})-(?:\d{2})-(?:\d{2})$/ console.log(str.replace(reg, "$1/$2/$3")) // $1/$2/$3
上面的例子就是一個非捕獲性的例子,在子表達式前面加上?:就能夠解除小括號的分組模式因此匹配不到
說到貪婪模式和非貪婪模式,首先我要介紹一下量詞,由於非貪婪模式要用在量詞後面
n{X}匹配包含X個n的序列的字符串 n{X,Y}匹配包含X至Y個n的序列的字符串 n{X,}匹配至少包含 X 個 n 的序列的字符串 n*匹配任何包含零個或多個 n 的字符串 n?匹配任何包含零個或一個 n 的字符串 n+匹配任何至少包含一個 n 的字符串 貪婪模式就是儘量多的匹配 let str = 'abcdefghijk123' let reg = /\w{1,4}/ console.log(str.replace(reg, "*")) // *efghijk123
上面的例子則爲貪婪模式它會匹配到最大的那個位數
let str = 'abcdefghijk123' let reg = /\w{1,4}?/ console.log(str.replace(reg, "*")) // *bcdefghijk123
上面的例子則爲非貪婪模式,只會去匹配最少的位數
先行斷言?= let str = 'abcdefghijk123asd456' let reg = /\w+(?=123)/g console.log(str.match(reg)) // ["abcdefghijk"]
上面的例子爲先行斷言的例子reg規則必須是後面帶有123的匹配到
先行否認斷言?! let str = 'bbb123 bbbbb456' let reg = /b{3,}(?!123)/g console.log(str.match(reg)) // ["bbbbb"]
後行斷言查找匹配表達式匹配到後面的 let str = 'abcdefghijk123asd456' let reg = /(?<=123)[a-z]/g console.log(str.match(reg)) // ["a"] 後行否認斷言,匹配不屬於123的,後面的[a-z]的字符 let str = 'abcdefghijk123asd' let reg = /(?<!123)[a-z]+/g console.log(str.match(reg)) // ["abcdefghijk", "sd"]
我感受先行斷言像後行否認斷言,先行否認斷言像後行斷言
new RegExp(pattern,modifiers) pattern 則爲表達式 modifiers 則爲修飾符 let reg1 = new RegExp('[a-z]','g') console.log(reg1) // /[a-z]/g
上面的例子咱們會獲得這個結果是由於RegExp對象會將第二個參數修飾符與第一個參數表達式進行合併
let reg1 = new RegExp(/[a-z]/,'g') console.log(reg1) // /[a-z]/g
上面這個例子咱們也會獲得咱們想要匹配全局的一個表達式,可是在es5中若是這樣寫就會出現報錯
let reg1 = new RegExp(/[a-z]/,'g') console.log(reg1.flags) // g let reg1 = new RegExp(/[a-z]/,'i') console.log(reg1.flags) // i
咱們還能夠檢測表達式是否使用了修飾符,而且能夠知道使用了什麼修飾符
compile | 編譯正則表達式 |
---|
let str = '123.jpg456.png' let reg = /[123]/g console.log(str.replace(reg, 'x')) // xxx.jpg456.png reg.compile(/[456]/g) console.log(str.replace(reg, 'x')) // 123.jpgxxx.png let str = '123.jpg456.png' let reg = /[123]/g console.log(str.replace(reg, 'xx')) // xxxxxx.jpg456.png
上面的第一個例子使用了表達式方法compile它會使表達式從新編譯或是修改,因此第一次匹配的是123,第二次則是456,是由於改變了匹配機制,第二個例子使用用到了替換的方法而且會發現你替換的參數多的話會修改字符串的長度
exec | 根據正則表達試查找對應的字符和位置 |
---|
let str = '2018-02-13' let reg = /-\d{1,2}/g console.log(reg.exec(str)) // ["-02", index: 4, input: "2018-02-13", groups: undefined]
上面的例子是查找帶有-數字不超過2位,返回的是數組,而且把匹配到的第一個在最前面的位置
test | 根據正則表達試是否匹配到布爾值 |
---|
search | 檢索與正則表達式相匹配的值 |
---|
let str = '2018-02-13' let reg = /-\d{1,2}/g console.log(str.search(reg)) // 4
它會返回你表達式匹配到第一個字符的位置返回,它會對大小寫敏感若是查找不到會返回-1,無視g
match | 找到一個或多個正則表達式的匹配 |
---|
let str = 'this is 1 or 2' let reg = /\d/g console.log(str.match(reg)) // [1,2]
它會找出全部與你表達式匹配到的字符放入數組中
replace | 替換 |
---|
replace替換咱們上面已經使用過不少次了,你們能夠仔細閱讀看
matchAll | 匹配全部,表達式不用使用全局修飾符 |
---|
es6的正在提案的一個方法,它能夠摒棄全局的修飾符,達到全局的匹配,它會返回一個遍歷器,而後能夠經過結構賦值拿到想要的結果
/^1[3|4|5|7|8][0-9]{9}$/ 匹配手機號開頭必須有1,34578其中的一個,結尾必須9位數並且是0-9的數字 /^0315(-?)[0-9]{7}$/ 判斷電話區號和-無關緊要 /^[0-9]{4}(-?)[0-9]{7}$/ 匹配1-9的數字必須是四位,無關緊要-,匹配7位數字
都是幾個比較簡單的表達式,還需多學習,多練習才能寫出更普遍更精準的表達式