<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
正規表示式,名字聽上去就沒有吸引力,我發現很多前端對正規表示式瞭解不深,甚至有些懼怕,每次能夠執行全憑運氣,更有甚者完全靠複製貼上。
正規表示式其實並不難,語法就那麼多,而且一旦掌握在某些時候能夠給解決問題提供捷徑,更重要的是面試可能會被問到,要是不會那就尷尬了。
本文全面介紹正規表示式的語法知識,全面介紹JavaScript中正規表示式的API,通過實戰,希望能夠幫助大家全面學習,並啃下前端的難題。
下面是我對正則的理解:
正則就是用有限的符號,表達無限的序列,殆已!
正規表示式的語法一般如下(js),兩條斜線中間是正則主體,這部分可以有很多字元組成;i
部分是修飾符,i
的意思表示忽略大小寫
/^abc/i
正則定義了很多特殊意義的字元,有名詞,量詞,謂詞等,下面逐一介紹
沒有特殊意義的字元都是簡單字元,簡單字元就代表自身,絕大部分字元都是簡單字元,舉個例子
/abc/ // 匹配 abc /123/ // 匹配 123 /-_-/ // 匹配 -_- /海鏡/ // 匹配 海鏡
是跳脫字元,其後面的字元會代表不同的意思,跳脫字元主要有三個作用:
第一種,是為了匹配不方便顯示的特殊字元,比如換行,tab符號等
第二種,正則中預先定義了一些代表特殊意義的字元,比如w
等
第三種,在正則中某些字元有特殊含義(比如下面說到的),跳脫字元可以讓其顯示自身的含義
下面是常用跳脫字元列表:
n | 匹配換行符 |
r | 匹配回車符 |
t | 匹配製表符,也就是tab鍵 |
v | 匹配垂直製表符 |
x20 | 20是2位16進位制數位,代表對應的字元 |
u002B | 002B是4位元16進位制數位,代表對應的字元 |
u002B | 002B是4位元16進位制數位,代表對應的字元 |
w | 匹配任何一個字母或者數位或者下劃線 |
W | 匹配任何一個字母或者數位或者下劃線以外的字元 |
s | 匹配空白字元,如空格,tab等 |
S | 匹配非空白字元 |
d | 匹配數位字元,0~9 |
D | 匹配非數位字元 |
b | 匹配單詞的邊界 |
B | 匹配非單詞邊界 |
\ | 匹配本身 |
有時我們需要匹配一類字元,字元集可以實現這個功能,字元集的語法用[``]
分隔,下面的程式碼能夠匹配a或b或c
[abc]
如果要表示字元很多,可以使用-
表示一個範圍內的字元,下面兩個功能相同
[0123456789] [0-9]
在前面新增^
,可表示非的意思,下面的程式碼能夠匹配a``b``c
之外的任意字元
[^abc]
其實正則還內建了一些字元集,在上面的跳脫字元有提到,下面給出內建字元集對應的自定義字元集
如果我們有三個蘋果,我們可以說自己有個3個蘋果,也可以說有一個蘋果,一個蘋果,一個蘋果,每種語言都有量詞的概念
如果需要匹配多次某個字元,正則也提供了量詞的功能,正則中的量詞有多個,如?
、+
、*
、{n}
、{m,n}
、{m,}
{n}
匹配n次,比如a{2}
,匹配aa
{m, n}
匹配m-n次,優先匹配n次,比如a{1,3}
,可以匹配aaa
、aa
、a
{m,}
匹配m-∞次,優先匹配∞次,比如a{1,}
,可以匹配aaaa...
?
匹配0次或1次,優先匹配1次,相當於{0,1}
+
匹配1-n次,優先匹配n次,相當於{1,}
*
匹配0-n次,優先匹配n次,相當於{0,}
正則預設和人心一樣是貪婪的,也就是常說的貪婪模式,凡是表示範圍的量詞,都優先匹配上限而不是下限
a{1, 3} // 匹配字串'aaa'的話,會匹配aaa而不是a
有時候這不是我們想要的結果,可以在量詞後面加上?
,就可以開啟非貪婪模式
a{1, 3}? // 匹配字串'aaa'的話,會匹配a而不是aaa
有時我們會有邊界的匹配要求,比如以xxx開頭,以xxx結尾
^
在[]
外表示匹配開頭的意思
^abc // 可以匹配abc,但是不能匹配aabc
$
表示匹配結尾的意思
abc$ // 可以匹配abc,但是不能匹配abcc
上面提到的b
表示單詞的邊界
abcb // 可以匹配 abc ,但是不能匹配 abcc
有時我們想匹配x或者y,如果x和y是單個字元,可以使用字元集,[abc]
可以匹配a
或b
或c
,如果x和y是多個字元,字元集就無能為力了,此時就要用到分組
正則中用|
來表示分組,a|b
表示匹配a
或者b
的意思
123|456|789 // 匹配 123 或 456 或 789
分組是正則中非常強大的一個功能,可以讓上面提到的量詞作用於一組字元,而非單個字元,分組的語法是圓括號包裹(xxx)
(abc){2} // 匹配abcabc
分組不能放在[]
中,分組中還可以使用選擇表示式
(123|456){2} // 匹配 123123、456456、123456、456123
和分組相關的概念還有一個捕獲分組和非捕獲分組,分組預設都是捕獲的,在分組的(
後面新增?:
可以讓分組變為非捕獲分組,非捕獲分組可以提高效能和簡化邏輯
'123'.match(/(?:123)/) // 返回 ['123'] '123'.match(/(123)/) // 返回 ['123', '123']
和分組相關的另一個概念是參照,比如在匹配html標籤時,通常希望<xxx></xxx>
後面的xxx
能夠和前面保持一致
參照的語法是數位
,數位代表參照前面第幾個捕獲分組,注意非捕獲分組不能被參照
<([a-z]+)></1> // 可以匹配 `<span></span>` 或 `<div></div>`等
如果你想匹配xxx前不能是yyy,或者xxx後不能是yyy,那就要用到預搜尋
js只支援正向預搜尋,也就是xxx後面必須是yyy,或者xxx後面不能是yyy
1(?=2) // 可以匹配12,不能匹配22 1(?!2) // 可有匹配22,不能匹配12
預設正則是區分大小寫,這可能並不是我們想要的,正則提供了修飾符的功能,修復的語法如下
/xxx/gi // 最後面的g和i就是兩個修飾符
g
正則遇到第一個匹配的字元就會結束,加上全域性修復符,可以讓其匹配到結束
i
正則預設是區分大小寫的,i
可以忽略大小寫
m
正則預設情況下,^和只能匹配字串的開始和結尾,m修飾符可以讓和只能匹配字串的開始和結尾,m修飾符可以讓^和只能匹配字串的開始和結尾,m修飾符可以讓和匹配行首和行尾,不理解就看例子
/jing$/ // 能夠匹配 'yanhaijing,不能匹配 'yanhaijingn' /jing$/m // 能夠匹配 'yanhaijing, 能夠匹配 'yanhaijingn' /^jing/ // 能夠匹配 'jing',不能匹配 'njing' /^jing/m // 能夠匹配 'jing',能夠匹配 'njing'
有時我們會遇到特別複雜的正則,有時候可能不太直觀,下面推薦一個圖形化展示的工具,我們把涉及到的語法羅列一下
/^[a-z]*[^d]{1,10}?(aaa|bbb)(?:ccc)$/
可以看到工具能夠更快的幫我們理清頭緒
在js中建立正則有兩種辦法,字面量和new,和建立其他型別變數一樣
var reg = /abc/g // 字面量 var reg = new RegExp('abc', 'g') // new方式,意思和上面一樣
js中用到正則的地方有兩個入口,正則的api和字串的api,RegExp#test
等於RegExp.prototype.test
每個正則範例都有test方法,test的引數是字串,返回值是布林值,表示當前正則是否能匹配指定的字串
/abc/.test('abc') // true /abc/.test('abd') // false
exec使用方法和test一樣,只是返回值並不是布林值,而是返回匹配的結果
匹配成功返回一個陣列,陣列第一項是匹配結果,後面一次是捕獲的分組
/abc(d)/.exec('abcd') // ["abcd", "d", index: 0, input: "abcd"]
此陣列還有另外兩個引數,input是輸入的字串,index表示匹配成功的序列在輸入字串中的索引位置
如果有全域性引數(g),第二次匹配時將從上次匹配結束時繼續
var r1 = /ab/ r1.exec('ababab') // ['ab', index: 0] r1.exec('ababab') // ['ab', index: 0] var r2 = /ab/g r2.exec('ababab') // ['ab', index: 0] r2.exec('ababab') // ['ab', index: 2] r2.exec('ababab') // ['ab', index: 4]
這一特性可以被用於迴圈匹配,比如統計字串中abc的次數
var reg = /abc/g var str = 'abcabcabcabcabc' var num = 0; var match = null; while((match = reg.exec(str)) !== null) { num++ } console.log(num) // 5
如果匹配失敗則返回null
/abc(d)/.exec('abc') // null
search方法返回匹配成功位置的索引,引數是字串或正則,結果是索引
'abc'.search(/abc/) // 0 'abc'.search(/c/) // 2
如果匹配失敗則返回-1
'abc'.search(/d/) // -1 'abc'.search(/d/) !== -1 // false 轉換為布林值
match方法也會返回匹配的結果,匹配結果和exec類似
'abc'.match(/abc/) // ['abc', index: 0, input: abc] 'abc'.match(/abd/) // null
如果有全域性引數(g),match會返回所有的結果,並且沒有index和input屬性
'abcabcabc'.match(/abc/g) // ['abc', 'abc', 'abc']
字串的split方法,可以用指定符號分隔字串,並返回資料
'a,b,c'.split(',') // [a, b, c]
其引數也可以使一個正則,如果分隔符有多個時,就必須使用正則
'a,b.c'.split(/,|./) // [a, b, c]
字串的replace方法,可以將字串的匹配字元,替換成另外的指定字元
'abc'.replace('a', 'b') // 'bbc'
其第一個引數可以是正規表示式,如果想全域性替換需新增全域性引數
'abc'.replace(/[abc]/, 'y') // ybc 'abc'.replace(/[abc]/g, 'y') // yyy 全域性替換
在第二個引數中,也可以參照前面匹配的結果
'abc'.replace(/a/, '$&b') // abbc $& 參照前面的匹配字元 'abc'.replace(/(a)b/, '$1a') // aac &n 參照前面匹配字元的分組 'abc'.replace(/b/, '$'') // aac $` 參照匹配字元前面的字元 'abc'.replace(/b/, "$'") // acc $' 參照匹配字元后面的字元
replace的第二個引數也可以是函數,其第一個引數是匹配內容,後面的引數是匹配的分組
'abc'.replace(/w/g, function (match, $1, $2) { return match + '-' }) // a-b-c-
RegExp是一個全域性函數,可以用來建立動態正則,其自身也有一些屬性
來個例子
/a(b)/.exec('abc') // ["ab", "b", index: 0, input: "abc"] RegExp.$_ // abc 上一次匹配的字串 RegExp.$1 // b 上一次匹配的捕獲分組 RegExp.input // abc 上一次匹配的字串 RegExp.lastMatch // ab 上一次匹配成功的字元 RegExp.length // 2 上一次匹配的陣列長度
正規表示式的範例上也有一些屬性
還是看例子
var r = /abc/igm; r.flags // igm r.ignoreCase // true r.global // true r.multiline // true r.source // abc
lastIndex比較有意思,表示上次匹配成功的是的索引
var r = /abc/igm; r.exec('abcabcabc') r.lastIndex // 3 r.exec('abcabcabc') r.lastIndex // 6
可以更改lastIndex讓其重新開始
var r = /abc/igm; r.exec('abcabcabc') // ["abc", index: 0] r.exec('abcabcabc') // ["abc", index: 3] r.lastIndex = 0 r.exec('abcabcabc') // ["abc", index: 0]
來幾個常用的例子
/(?:0d{2,3}-)?d{7}/ // 電話號 010-xxx xxx /^1[378]d{9}$/ // 手機號 13xxx 17xxx 18xxx /^[0-9a-zA-Z_]+@[0-9a-zA-Z]+.[z-z]+$/ // 郵箱
去除字串前後空白
str = str.replace(/^s*|s*$/g, '')
刻意練習,方能遊刃有餘,知己知彼,方能百戰百勝,正則是前端的一個武器,技多不壓身。
到這裡你已經學會了正則的語法,並且學會了在js中使用正則的方法,接下來快去實戰吧,要想學會正則必須多加練習,正所謂拳不離手曲不離口嗎。
到此這篇關於全面學習正規表示式 - 從原理到實戰的文章就介紹到這了,更多相關正規表示式原理到實戰內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45