本文原創:liuchendi正則表達式
字面量方式建立數組
let reg = /元字符/修飾符bash
實例方式建立函數
letg reg = new RegExp('\d+',igm)//實例化建立正則的方式不須要加/(並不包括轉義斜槓\),並把修飾符以第二個參數的形式傳遞給實例測試
經過實例方式建立的正則,其中特殊元字符須要再加上一個\,由於字符串中的\也是表明轉義的意思,就會默認省略ui
let reg = new RegExp('\\b${cn}\\b')
複製代碼
正則表達式沒法識別連續的單詞中的字符或者數字,他會默認把他們當作一個一個單獨的字符去識別url
let reg = /[12-66]/ //表示1或2-6或5
複製代碼
回車打下的換行還自帶一個空格spa
當你要檢測字符串\d時prototype
let reg = /\\d/
reg.test('\\d')
//字符串中的斜槓首先就是一個轉義運算符,你要想測試\d
//字符串自己的\還要進行轉義
複製代碼
量詞限制的是前面緊跟的某個字符出現的次數rest
let reg = /^[a-z]$/
console.log(reg.test('aa')) // false 注意:這個是表示一個字母既是開頭又是結尾,而且是一個字母
複製代碼
正則當中小括號改變優先級
let reg = /^a|b$/ //以a爲開頭或者以b爲結尾
let reg3 = /^(a|b)$/ //至關於/^a$/或/^b$/
複製代碼
分組捕獲
分組引用
let reg = /^1(\d)\1\1$/
console.log(reg.test('1222')) // true
console.log(reg.test('1333')) // true
let reg2 = /^([a-z])([a-z])\2\1$/
console.log(reg2.test('abba')) // true
console.log(reg2.test('baba')) // false
複製代碼
在這裏如何計算他是第幾個分組,就從左往右看,看他的左括號是第幾個
正則捕獲:將匹配到的內容,捕獲出來,做爲返回值返回給咱們。方法的位置:RegExp.prototype.exec()
他的返回值是一個數組,若是沒有捕獲到返回值爲null
index、groups、input都是是正則捕獲到的數組的自帶屬性,這個數組的長度爲1
每次調用正則捕獲或者匹配的時候都是從索引0處開始捕獲的
let reg = /\d+/
let str = 'abc111 abc222 abc333'
reg.exec(str)// ["111", index: 3, input: "abc111 abc222 abc333", groups: undefined]
reg.exec(str)// ["111", index: 3, input: "abc111 abc222 abc333", groups: undefined]
reg.exec(str)// ["111", index: 3, input: "abc111 abc222 abc333", groups: undefined]
複製代碼
取消正則的懶惰性,修飾符g(global),會從上一次匹配或者捕獲成功的位置繼續向後查找
若是捕獲到結束邊界 會從頭再來
let reg = /\d+/g
let str = 'abc111 abc222 abc333'
console.log(reg.exec(str))
// ["111", index: 3, input: "abc111 abc222 abc333", groups: undefined] test:true
console.log(reg.exec(str))
// ["222", index: 10, input: "abc111 abc222 abc333", groups: undefined] test:true
console.log(reg.exec(str))
// ["333", index: 17, input: "abc111 abc222 abc333", groups: undefined] testLtrue
console.log(reg.exec(str))
// null test:false
console.log(reg.exec(str))
// ["111", index: 3, input: "abc111 abc222 abc333", groups: undefined] test:true
複製代碼
lastIndex:他是正則實例上的一個屬性,下一次開始查找的起始索引
lastIndex的值能夠手動修改,可是若是沒有修飾符g的時候,修改不會起做用
reg.lastIndex = 9
複製代碼
不管是test仍是exec仍是混用,當加修飾符/g時,lastIndex屬性都是起決定性的因素。
let reg = /\d+/
reg.exec('abc111 abc222 abc333') //111 index=3
reg.exec('a444 b555 c666') //555
複製代碼
由於lastIndex是正則實例對象reg上的屬性,換字符串並不會影響他下面私有屬性的值
global屬性是用來標識正則是否有g修飾符的,返回值時true和false
multline屬性是否支持多行匹配
ignoreCase屬性是否忽略大小寫
sourse正則全部的元字符內容,不包括外界的兩個斜槓
match支持正則,在他的底層封裝的仍是exec,當沒有取消正則懶惰性的狀況下,他的返回值和exec相同,若是匹配不到返回值爲null
若是取消了正則的懶惰性,match會以數組的形式將捕獲到的結果一次性返回
正則的貪婪性:每一次捕獲的時候老是捕獲到知足當前正則的最長內容
取消正則的貪婪性:量詞後面加?,按照最短的狀況進行匹配
let reg = /\d{2,8}?/g
複製代碼
數組返回的第一項始終是整個大正則捕獲到的內容,若是有分組,會從第二項開始依次排列
let reg = /hello(\d+)/g
let str = 'hello2018 abc111 hello2019 abc222'
console.log(reg.exec(str))
// ["hello2018",2018, index: 0, input: "hello2018 abc111 hello2019 abc222", groups: undefined]
console.log(reg.exec(str))
// ["hello2019",2019, index: 0, input: "hello2018 abc111 hello2019 abc222", groups: undefined]
複製代碼
若是不加g,因爲match的底層就是exec,因此返回值和exec相同
若是加了g,因爲match是一次性捕獲,因此不能捕獲分組內容的
取消分組
在小括號的前面加上一個(?:)只匹配,不捕獲
let reg = /^(?:start|end)$/
複製代碼
let reg = /^1(\d)\1$/
複製代碼
\1是對分組1的再次引用,這裏存在幾個小問題,其一是引用的分組表示兩個分組的內容相同,第二個是經過引用的分組經過RegExp.$拿不到
let reg = /^([a-z])\1([a-z]\1)$/
//aabb ccdd
複製代碼
正向預查(?=元字符) 不會發生分組捕獲 負向預查(?!元字符) 不會發生分組捕獲
// 正向預查
// 捕獲 後面跟着3或者4的字母
let reg1 = /[a-z](?=3|4)/g
let str1 = 'a1 b2 c3 d4'
console.log(str1.match(reg1)) //["c", "d"]
// 負向預查
// 捕獲 後面跟着的不是3或者4的字母
let reg2 = /[a-z](?!3|4)/g
let str2 = 'a1 b2 c3 d4'
console.log(str2.match(reg2)) // ["a", "b"]
複製代碼
捕獲的不是預查的內容而是範圍內的內容
正向預查或者負向預查若是放在開頭的話,做用是限定後面的範圍\d,\w,[]
let reg11 = /^((?=3)\d)+$/
console.log(reg1.test('3333')) // true限定數字只能爲3
let reg2 = /^((?!4)\d)+$/g
console.log(reg2.test('1123123')) // true 限定數字裏不能有4
console.log(reg2.test('11234123')) // false
console.log(reg2.test('11234566')) // false
複製代碼
let reg = /^a.+b$/
let str = `a1b
a2b
a3b
`
reg.test(str)//false 由於沒有以a爲開頭,b爲結尾的
let reg1 = /^a.+b$/m
reg1.exec(str)//a1b 會把每一行都看做獨立的一行進行匹配
reg1.exec(str)//a2b
reg1.exec(str)//a3b
複製代碼
// let sss = '1a2b3c4'
// console.log(sss.split(/[a-z]/)) // [1, 2, 3, 4]
複製代碼
replace的底層封裝的也是exec,至關於自動的對exec進行遍歷
let str = 'aaa2018 bbb2019'
let reg = /hello/ //若是加g,匹配到多少次,這個函數就會被執行幾回
//他會把exec捕獲到的值當作參數傳遞給這個函數
//這個函數的返回值就是replace捕獲到的內容所要替換的值
str.replace(reg,(...rest)=>{
console.log(rest)
return 'AA'
})
複製代碼
這個函數的返回值就是匹配到的內容要替換的新內容,有點相似於數組的map方法
let str2 = str.replace(/\d\b/g, a => a * 2)
//第一個參數是正則捕獲到的內容,因爲沒有用擴展運算符,因此穿入的直接是變量而不是數組
複製代碼
方法一
let reg = \(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})\
str.replace(reg,`$1年$2月$3日 $4時$5分$6秒`)
str.replace(reg,function(...rest){
return `${rest[1]}年${rest[2]}月${rest[3]}日`
})
複製代碼
方法二
let time2 = time.split(/[-\s:]/)//[2019,20,1,11,56,56]
let text = ['年','月','日',' ','時','分','秒']
//forEach拼接
複製代碼
方法三
let ary = time.match(/\d+/g)
let text = ['年','月','日',' ','時','分','秒']
ary.map()//遍歷修改
複製代碼
let newStr = str.split('').sort().join('')
let reg = /(\w)\1*/g
let obj = {}
newStr.replace(reg,function(){
obj[rest[1]] = obj[rest[0].length]
})
複製代碼
let reg = /[?&]([^?&=]+)=([^?&=]+)/g
複製代碼
function format (num) {
var reg=/\d{1,3}(?=(\d{3})+$)/g;
return (num + '').replace(reg, '$&,');
}
複製代碼
let reg = /^1(36|58)\d{8}$/
複製代碼
let reg = /^[+-]?(\d|[1-9]\d+)(\.\d+)?$/
複製代碼
拆分爲三段23-29,30-59,60-66
let reg = /(2[3-9])|([3-5]\d)|(6[0-6])/
複製代碼
第一部分能夠爲\w和. - ,可是. -不能做爲開頭和結尾i,不能連續
第二部分域名只能爲數字字母
let reg = /^\w+([-.]\w+)*@[\da-zA-Z]{2,6}(\.[a-z]{2,6}){1,2}$/
複製代碼
function testType(data){
let str = Object.prototype.tostring.call(data)
let reg = /\[object (\w+)\]/
return str.exec(reg)[1].toLowerCase()
}
複製代碼