正則表示式-溫故而知新
正則表示式
重新整理學習,為了加深印象,發現了之前遺漏的一個非常重要的知識點優先選擇最左端的匹配結果 ,這個規則
js上建立正則的方式
-
直接字面量的建立
const r = /xx/;//通過雙斜槓,在中間新增匹配的規則,這樣就是一個正則表示式了
-
通過建構函式建立
const r = new RegExp('xx', g)//通過建構函式來建立正則物件,第一個引數為匹配規則字串,第二個引數可以新增修飾符,例如g,i,m,y
正則的例項方法
-
常用的
exec
,可以返回一個類陣列,資訊比較全const r = /a/g r.exec('asd')//返回["a", index: 0, input: "asd", groups: undefined]0: "a"groups: undefinedindex: 0input: "asd"length: 1__proto__: Array(0)
可以看看返回的資訊有些什麼?
-
一個元素代表:整體匹配返回的結果,如果正則中有子組匹配,那麼會在
index
元素前返回,例如/(a)s/g.exec('afasg')// 返回 ["as", "a", index: 2, input: "afasg", groups: undefined]
-
index
就是匹配的索引位置資訊 -
input
就是目標字串是什麼, -
groups
這邊返回undefined,因為正則中沒用到;它是返回自定義名字的子匹配資訊,例如/(?<groupone>a)s/g.exec('afasg') //返回["as", "a", index: 2, input: "afasg", groups: {groupone: "a"}]
-
-
不常用的方法
test
,返回Boolean值,表示是否有匹配的字串
正則的重要規則
我講講幾個比較重要的,常用的
-
修飾符:
i,m,g,y
,修飾符之間可以同時使用i就是忽略大小寫,例如驗證碼上的引用
=>/a/i.test('A')//true
m就是能識別換行,能將判斷出行末
/a$/.test('a\nb')//false /a$/m.test('a\nb')//true
g是能進行連續的匹配,當匹配成功一次後還能繼續匹配直到沒有為止,並且可以通過lastIndex可以檢視下一次匹配的開始的索引
但是隻對同一個正則有效,能連續指定,不然都是從零開始,這裡的同一個是指記憶體地址相等,不是內容相等就夠了const r = /a/g//這裡通過變數r定義這樣用r進行後面的操作都會是用一個 r.lastIndex//0 r.test('asdasd')//true r.lastIndex//1
y一般和g連用,y的作用是必須從一開始就匹配上,不然就false;相當於加了個^
/a/y.test('ba')//false /a/y.test('ab')//true ,一般和g連用,進行連續頭部匹配是否成功
-
\b,\B
用於匹配是否是詞的邊界,不存在/wbw/它的意思就是是否存在一個是詞的邊,但前面又有一個w,明顯是不存在的(w等價於[A-Za-z0-9_])/\ba/g.test('ad') //true /\ba/g.test('bad') //false /\ba/g.test('c-ad') //true \B就是取反不是詞的邊界
-
[],()之間的區別,這兩個分成常用
[]
僅僅代表一個字串,不管裡面寫多少規劃,最終還是會去匹配一個字串常用的有
[xyz]//代表匹配x或者y或者z [^]//等價於[^''],任意字串 [\S\s]//任意字串,\s是匹配空格,換行(一些帶有空格的u碼,詳細可以看連結) \S就是匹配除了\s意外的字串
()
是用於取子匹配的值,又叫元組;有時候我們整體匹配上了,但又想在裡面取某個值就可以加上個括號,結果中就會幫你返回,在將exec
時以及提到了,這邊不舉例了可以和字串的replace方法一起使用,進行負複雜的操作
const r = /he(b)/g 'afdhjbkhbgd'.replace(r, (match, $1) => { //match 是整體匹配的結果,$1是第一個元組返回值,當多個元組存在時是有外到裡的 return xxxx })
-
.
代表一個字元,除了空格,類似換行;還有一些大於大於0xFFFF
的字元,他會認為這是兩個字元,所以用於簡單的任意字串匹配,可用.
代表 -
量詞
a{n}
可以用來代表去匹配n個a,還可以寫區間{1,3}匹配1到3個+,*,?
這些事貪婪匹配的量詞,就是數量往大了取,不固定,但又範圍+//[1, Infinity]*//[0, Infinity]?//[0, 1]
如果在其後面再添加個
?
就是非貪婪匹配了,取值就儘量往小了取非貪婪匹配的作用在哪,可以通過一個簡單的例子看一下
//如果要匹配字元換'caabaaab' ,如果只想取aab就會用到非貪婪匹配 通過/a+?b/g來匹配;用?來指定非貪婪匹配,加上b的限制,不會取到1;這邊用+還是*是一樣的
-
強大的斷言
可以理解成你是用於匹配的規則但不是我想要輸出的內容
-
非捕獲組
用?:
表示;說直白點就是:還是這麼匹配但是我不返回括號裡的內容,所以我們進行split的組匹配時可以進行修改console.log("abc".split(/(?:b)/));//["a", "c"]
-
先行斷言
用x(?=y)
表示,意思是匹配一個x,x必須在y前面,結果中不返回y -
先行否定斷言
用x(?!y)
表示,意思是匹配一個x,x後面不能是y,結果中不返回y -
後行斷言
用(?<=y)x
表示,意思是匹配一個x,x前面必須是y,結果中不返回y -
後行否定斷言
用
(?<!=y)x
表示,意思是匹配一個x,x前面不能是y,結果中不返回yconsole.log(/(?<!=b)a/.exec("bcaba"));//["a", index: 2, input: "bcaba", groups: undefined] console.log(/(?<=b)a/.exec("bcaba"));//["a", index: 4, input: "bcaba", groups: undefined]
-
非捕獲組
最重要最優先的規則
-
優先選擇最左端的匹配結果
可以通過幾個例子自證一下
/a+?b/.exec('baaabab') //結果["aaab", index: 1, input: "baaabab", groups: undefined],因為先匹配上了aaab,所以忽略非貪婪原則不輸出ab或者b /a*?/.exec('baaa') //返回["", index: 0, input: "baaa", groups: undefined]因為先匹配上了空串所以結果為空串
常見的正則例子
-
去除首尾空格
' fds df '.replace(/^\s*|\s*$/g, '')
-
去除首尾空格
' fds df '.replace(/\s*(?=\S*)/g, '')
-
千分位數字格式化
'1234567890'.replace(/\B(?=((\d{3})+$))/g, '.')
;
如果有小數,('1234567890.123').replace(/\B(?=((\d{3})+\.))/g, ',')