本文主要介紹了捕獲和非捕獲的概念,並舉了一些例子,這些都是正則表達式在js中進階的一些用法。後面有彩蛋哦javascript
通常用()括住的就是捕獲組,並且相似於算術中的括號,從左到右,逐層去括號。好比存在(A)((B)C)這種,他捕獲到的將會是(A)((B)C)、(B)、((B)C),並在內存中存放,能夠經過RegExp對象的$屬性來訪問到。java
/(1((2)3))/.test('123')
RegExp.$1 //123
RegExp.$2 //23
RegExp.$3 //2
複製代碼
/(((1)2)3)/.test('123')
RegExp.$1 //123
RegExp.$2 //12
RegExp.$3 //1
複製代碼
這個順序,按左括號的順序來算的,第幾個(
就表示第幾個$符號屬性,通常從1開始,最多$9git
還有一些舊的RegExp長屬性名,在高級程序設計108頁裏面 github
因而,咱們常常有一個這樣的需求,將一個這樣子的字符串轉爲數組: "[a,[b],c]"
,我知道不少人確定說JSON.parse,恭喜,答對了。正則表達式
而後控制檯給你的的獎勵是: Uncaught SyntaxError: Unexpected token a數組
在這裏轉過去的不是字符串abc,而是變量abc,因此就直接報錯:Unexpected token a in JSON at position 1,想要parse,那麼這個字符串應該是這樣子"['a',['b'],'c']"
,這時候,咱們能夠用正則把他們換掉: "[a,[b],c]".replace(/\w+/g,"'$&'")
,性能優化
上面高程都說了$&匹配的是最近匹配的結果,咱們把匹配到的字串變成被兩個引號包圍的字符串,此次在parse就能正經常使用了。函數
另外,簡寫的話仍是有不少不兼容的問題的,最好寫全稱性能
有的人就問,用正則怎麼匹配AABB類型的詞語?好比高高興興、亮晶晶這些。在正則裏面反斜槓+數字就能夠作到,表示重複第n個捕獲組的內容,這個n和上面$後面的數字同理:優化
/(.)\1(.)\2/.test('高高興興') //TRUE,第一個和第二個相同,第三四個相同
/(.)(.)\2/.test('亮晶晶') // TRUE ,後面兩個相同
複製代碼
replace第二個參數還能夠是一個函數,他的參數是matches,...catches,index
。便是匹配結果,捕獲組,匹配位置,準確來講,第一個參數是匹配結果,最後一個參數是匹配位置,中間全部的參數都是捕獲組。 因而對於一個常見的小需求:讓字符串的連續字符變成一個 'aaaabbbbccc' =>'abc'
咱們能夠這樣子寫
'aaaabbbbccc' .replace(/(\w)\1+/g,function(a){
return a[0]
})
//固然還能夠這樣子
'aaaabbbbccc' .replace(/(\w)\1+/g,'$1')
//還能夠手動設置
'aaaabbbbccc' .replace(/(\w)\1+/g,function(a){
return a
}(1))//111
複製代碼
以 (?) 開頭的組是非捕獲組,它不捕獲文本 ,也不針對組合計進行各類操做,不將匹配到的字符存儲到內存中,從而節省內存。也就是上面所講的$屬性他都不會具備。通常用於只須要檢測結果的狀況。 (?:a)非捕獲一個a
/(?:a)1(?:b)/.test('a1b') //true
RegExp.$1 //''
複製代碼
var reg = /(?:\d{4})-(\d{2})-(\d{2})/
var date = '2018-01-02'
reg.test(date)
RegExp.$1 // 01
RegExp.$2 // 02
複製代碼
也有人叫前瞻,顧名思義,就是往前面(右邊)看,看看是否是某個東西。 (?=x) 匹配後面是x的數據 : /i am (?=a)/.test('i am a') //你右邊是a
(?!x) 匹配後面不是x的數據 /i am (?!a)/.test('i am b') //你右邊不是a
(?!B)[A-Z]:在大寫字母集合中,除去B
/(?!B)[A-Z]/.test('A') //true
/(?!B)[A-Z]/.test('B') //false
複製代碼
*? 重複0次或更屢次 +? 重複一次或更屢次 ?? 重複0次或一次 {n,}? 重複n次或更屢次 {n,m}? 重複n到m次
以上全部的匹配都是儘量的少重複,只要知足條件就好了,不繼續匹配了,在某個程度來講也是性能優化的方法之一。 那麼貪婪模式就是沒有作了上面的措施的都屬於貪婪模式,好比正則元字符、量詞單獨出現的狀況。
對於字符串'abbba'使用/ab*/g和/ab*? /g 貪婪模式:ab* 結果:abbb 和 a,第一次找到了a,繼續找發現後面接幾個b也是符合的,直到發現了第二個a才中止,再找到第二個a 惰性匹配:ab*? 結果:a 和 a,第一次找到了a,*的要求是不須要b也能夠,因此中止,接着又找到第二個a
檢測一個數是不是質數的方法 相信你們都見過一個很強大的函數,一行代碼判斷出一個數是否是質數:
function isPrime(n){
return n<2?false:!/^(11+?)\1+$/.test(Array(n+1).join('1'))
}
複製代碼
看上去好像很牛逼,容我細細道來: 首先最小的質數是2,因此先判斷是否小於2 若是大於2,先建立一個長度是n的字符串,裏面鋪滿了1。Array(n+1)建立n+1個空位(undefined),再用1做爲分隔符分開轉化爲字符串,因此就獲得一個長度爲n的字符串,全是1組成
for(var i = 2;i<n;i++){
if(n%i==0){return false}
}
return true
複製代碼
正則的強大,真的是法力無邊。jQuery做者的正則,號稱世界上最強的選擇器sizzle,就是強大正則作出來的(晚點再更新sizzle解讀)