前言:在常規的開發中正則或許是不須要徹底掌握,可是隨着技術的深刻挖掘或者說要深刻某一個框架源碼
解析在或者尋找一些平常處理字符串
的更好的處理方式,那麼正則表達式能夠說是必不可少
的。下面就隨着我開始從從淺到深一步一步的揭開正則表達式的神祕面紗。html
正則表達式有幾種呈現方式?
元字符是什麼?經常使用的有哪些?
經常使用的修飾符都有哪些?
什麼是正則的貪婪模式和非貪婪模式
咱們能夠用一個例子來看一下如下兩個的方式有何不一樣。git
🌰 【文本中是否含有test的字段】
:es6
let str = 'this is test'; console.log(str.indexOf('test') !== -1) // true console.log(str.includes('test')) // true
簡寫
//
: 兩個斜槓它的含義其實跟數組[]
相似都屬於簡寫。舉幾個簡單字的例子看一下:github
🌰 正則:正則表達式
// 文本中是否含有test的字段 let str = 'this is test'; let res = /test/ console.log(res.test(str)) // true
構造函數
new RegExp(pattern[, flags])
:構造函數的方式進行建立,應用場景不是不少,可是支持動態傳參。對於一些須要動態配置規則的場景仍是頗有幫助的。數組
🌰 正則:框架
// 找出含有test的文本 let str = 'this is test'; function foo(r, s) { const re = new RegExp(r) return re.test(s) } let res1 = foo('test', str); // true let res2 = foo('test1', str); // false
元字符就是擁有特定功能的特殊字符,大部分須要加反斜槓進行標識,以便於跟普通字符進行區分,而少數的元字符則須要加上反斜槓,以便於轉義爲普通字符使用。函數
常見的元字符列表
字符 | 描述 |
---|---|
\ |
將下一個字符標記爲一個特殊字符、或一個原義字符、或一個 向後引用、或一個八進制轉義符。例如,'n' 匹配字符 "n"。'\n' 匹配一個換行符。序列 '\' 匹配 "\" 而 "(" 則匹配 "("。 |
^ |
匹配輸入字符串的開始位置。若是設置了 RegExp 對象的 Multiline 屬性,^ 也匹配 '\n' 或 '\r' 以後的位置。 |
$ |
匹配輸入字符串的結束位置。若是設置了RegExp 對象的 Multiline 屬性,$ 也匹配 '\n' 或 '\r' 以前的位置。 |
* |
匹配前面的子表達式零次或屢次。例如,zo 能匹配 "z" 以及 "zoo"。 等價於{0,}。 |
+ |
匹配前面的子表達式一次或屢次。例如,'zo+' 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等價於 {1,}。 |
? |
匹配前面的子表達式零次或一次。例如,"do(es)?" 能夠匹配 "do" 或 "does" 。? 等價於 {0,1}。 |
{n} |
n 是一個非負整數。匹配肯定的 n 次。例如,'o{2}' 不能匹配 "Bob" 中的 'o',可是能匹配 "food" 中的兩個 o。 |
{n,} |
n 是一個非負整數。至少匹配n 次。例如,'o{2,}' 不能匹配 "Bob" 中的 'o',但能匹配 "foooood" 中的全部 o。'o{1,}' 等價於 'o+'。'o{0,}' 則等價於 'o*'。 |
{n,m} |
m 和 n 均爲非負整數,其中n <= m。最少匹配 n 次且最多匹配 m 次。例如,"o{1,3}" 將匹配 "fooooood" 中的前三個 o。'o{0,1}' 等價於 'o?'。請注意在逗號和兩個數之間不能有空格。 |
. |
匹配除換行符(\n、\r)以外的任何單個字符。要匹配包括 '\n' 在內的任何字符 |
查看更多post
說一千道一萬還不如來幾個例子看看元字符如何使用
🌰 栗子:this
找到字符串的特殊字符
let str = '.-&*' let re = /[\.\-\&\*]+/ console.log(re.test(str)) // true
利用轉義字符進行匹配特殊的字符好比說:\-
、\&
、\.
等等跟原生的JavaScript的轉義原理一致。
上圖:
🌰 栗子:
判斷字符串是否以數字開頭字母結尾
let str = 'abc123' let re = /^[a-z]+[0-9]+$/; re.test(str) // true
講解: ^
是以xxx開始,&
是以xxx結束,在[a-z]
表示在a-z字符中隨便一個,+
一次或者屢次。
上圖:
🌰 栗子:
替換日期的格式
let str = '2019-10-1' let re = /(\d+)\-(\d+)\-(\d+)/; let result = str.replace(re, `$1年$2月$3日`); console.log(result) // 2019年10月1日
講解: 利用元字符()
分組的概念能夠拿到匹配的分組名稱,而後進行本地替換。
上圖:
🌰 栗子:
匹配16進制的顏色值
let str = '#ffbbad #Fc01DF #FFF #ffE' let regex = /#[0-9a-zA-Z]{3,6}/g; console.log(str.match(regex));
講解:找到16進制符的規律,使用{3,6}
的形式進行匹配 最少3
次,最多6
次 。
上圖:
以上是對元字符怎麼使用有了簡單的介紹,想要掌握的更加詳細的話還須要多看多練多謝。下面看一下經常使用的修飾符。
g
:全局模式,表示查找字符串的所有內容,而不是找到一個匹配的內容就結束。🌰 栗子:
// 找出含有test的文本 let str = 'this is test test'; str.match(/test/); // 查詢第一次匹配項 str.match(/test/g);// 查找全部的匹配項 ['test','test']
關於字符串的match方法,請自行查閱。
i
:不區分大小寫,表示在查詢匹配時忽略pattern和字符串的大小寫。🌰 栗子:
// 找出含有test的文本 let str = 'this is TEST TEST'; str.match(/test/); // null str.match(/test/i);// 查詢到第一個TEST, str.match(/test/ig);// 全局查詢不分大小寫的test字符串
m
:多行模式,表示在查找到一行文本末尾時會繼續查找。須要注意的是:m的多行模式會修改^
和$
的行爲,默認狀況下^
和$
匹配字符串的開始處和結尾處,加上m
修飾符之後,^
和$
還會匹配行首和行尾,即^
和$
會識別換行符\n
。
PS: 都屬於元字符
會在以後面講到。
^
: 匹配輸入字符串的開始位置。$
:匹配輸入字符串的結束位置。🌰 栗子:
// 找出含有test的文本 let str = 'this is test\n' /test$/.test(str) // false /test$/m.test(str) // true
y
:粘附模式,表示只查找從lastIndex開始及以後的字符串。大白話解釋:y修飾符
其實和g修飾符
差相似,爲何說相似
呢?由於g修飾符
只要剩餘有位置存在
就行,而y修飾符
必須從剩餘的第一個位置
開始,這也就是粘連的含義。
🌰 栗子:
// 找出含有a的文本 let str = 'aaa_aa_a' let r1 = /a+/g; let r2 = /a+/y; r1.exec(str) // ['aaa'] r2.exec(str) // ['aaa'] r1.exec(str) // ['aa'] r2.exec(str) // null
解釋:一個使用g修飾符
,另外一個使用y修飾符
。這兩個正則表達式各執行了兩次,第一次執行的時候,二者行爲相同,剩餘字符串都是_aa_a
。因爲g修飾
沒有位置要求,因此第二次執行會返回結果,而y修飾符
要求匹配必須從頭部開始,因此返回null
。更多的細節
m
:Unicode 模式,啓用 Unicode 匹配。大白話解釋:會正確處理四個字節的 UTF-16 編碼。更多的細節
🌰 栗子:
let str = '𠮷'; /^.$/.test(str) // false /^.$/u.test(str) // true
s
:dotAll 模式,表示元字符.匹配任何字符(包括\n 或\r)。大白話解釋: 其實在元字符串的.
能夠表明任意的字符,可是不包括\n \r
等終止符,s修飾符
就是解決這個使用的。
🌰 栗子:
let str = 'hello\nworld' /hello.world/.test(str) // false /hello.world/s.test(str) // true
在說貪婪模式和非貪婪模式的話 須要先掌握一下什麼是量詞
,以下圖:
其實量詞屬於元字符的一種,你沒必要在乎這麼多的新名詞,可是至少你要知道它的做用靈活掌握。
舉一個例子看一下什麼是貪婪模式和非貪婪摸模式:
🌰 栗子:
貪婪模式
var regex = /\d{2,5}/g; var string = "123 1234 12345 123456"; console.log(string.match(regex)); // ["123", "1234", "12345", "12345"]
上圖:
非貪婪模式
var regex = /\d{2,5}?/g; var string = "123 1234 12345 123456"; console.log(string.match(regex)); // ["12", "12", "34", "12", "34", "12", "34", "56"]
上圖:
發現什麼不一樣了嗎?對了 就是多了一個?
只要在量詞後面加上?
表示的只要知足要求了 就不在往下匹配了。非貪婪模式 又稱惰性量詞
,
具體的能夠參考老姚的正則書 裏面很細緻的說明了正則的一些概念和方法論、建議時常讀一讀寫一寫。
其實關於正則的概念有不少、我這裏只是幫助你在複雜的正則世界裏鋪墊了一塊轉,入入門。以後還須要你本身去探索,有時間不妨看看我推薦的老姚的正則表達書,若是你也須要其餘的書籍來夯實你的基礎也能夠下載我整理的書籍列表,來免費下載。