本文主要經過對正則表達式的語法進行一些簡單的介紹,從而讓沒有接觸過或者想學習正則表達式的同窗有一個基礎的瞭解,從而可以看懂和編寫使用通常的正則表達式。javascript
本文的主要內容爲:java
本文的主要受衆是想要學習正則表達式又不知道從何入手的同窗。若是你已經使用過正則表達式,能夠快速瀏覽本文,強化本身的記憶便可。正則表達式
在正則表達式中,分爲精確匹配和模糊匹配兩種。顧名思義,精確匹配就是匹配特定的字符或者位置;而非精確匹配就是帶有必定的範圍的匹配。具體示例以下:瀏覽器
const reg1 = /ab/; //精確匹配 const reg2 = /ab+/; //模糊匹配
不一樣的匹配適用於不一樣的場景,你們根據本身的需求進行選擇便可。學習
在正則表達式中,咱們常常會遇到從N個字符裏面選取任意字符進行匹配的需求。這個時候,咱們就須要一個字符組。具體示例以下:spa
const reg = /[abc]/; // 與上面示例徹底相同,匹配a或b或者c
當匹配的字符多了之後,咱們不可能所有都列到字符組裏,所以咱們可使用範圍表示法。具體示例以下:code
const reg = /[a-c]/; // 匹配a或b或c
相同類的字符能夠用範圍,如1-九、A-Z或者a-z。在字符組中,-
是一個特殊字符,若是須要匹配-
,則須要使用\
進行轉義。cdn
固然,若是咱們是不想匹配N個字符中的任意一個,咱們能夠用排除字符組的方式來進行匹配。具體示例以下:ip
const reg = /[^abc]/; // 不匹配a、b、c中任意一個
排除字符組中也可使用範圍。字符串
當咱們須要匹配單個字符時,咱們可使用上面示例中的方法。可是,若是咱們須要匹配單個字符若干次呢?最簡單的方法就是將匹配的正則表達式寫若干次,可是這樣不只費時費力,還不方便閱讀。所以,正則表達式中使用了量詞來表示重複匹配N次的狀況。
量詞含義以下:
{m, }
,至少出現m次。{m, n}
,最少出現m次,最多出現n次(最多出現N次的寫法爲{0, n},而不是{, n})?
,匹配0或者1次+
,最少匹配1次,與{1, }
等價*
,匹配任意次,與{0, }
等價瞭解了上述量詞,下面咱們來看下這些量詞在示例中究竟是如何應用的:
const reg1 = /a+/; //至少匹配一次a const reg2 = /a?b*/; //匹配0或者1次a,再匹配任意次的b
如今問題來了,上面示例中的/a+/
這個正則表達式,若是遇到了字符串'aaa'
,那麼獲得的匹配結果是什麼呢?這個就涉及到了咱們下一節要介紹的內容。
貪婪匹配:全部的量詞都會盡量多的進行匹配,默認值。以/a+/
和'aaa'
爲例,匹配的結果是'aaa'
。
非貪婪匹配:全部的兩次都會盡量少的匹配。以/a+?/
和'aaa'
爲例,匹配的結果是'a'
。
由於貪婪匹配是默認值,因此當咱們寫正則表達式時,默認就是貪婪匹配。那麼咱們應該如何來表示非貪婪匹配呢?具體示例以下:
const reg1 = /a+/; //貪婪匹配 const reg2 = /a+?/; // 非貪婪匹配
經過上面的示例咱們能夠看到,咱們只須要在兩次後加上一個?
,就表示是一個非貪婪匹配。
注:非貪婪匹配只會向後做用,不會向前做用。即/a+?bb/匹配'aabb'是'aabb',而不是'abb';而/aab+?/則是匹配'aab'。(這個與正則表達式匹配和回溯的原理有關,有興趣的能夠閱讀個人下一篇關於正則表達式的博客)
在一個正則表達式中,咱們會遇到作選擇的狀況。單個元素進行選擇時,咱們可使用字符組。可是,若是須要多個元素好比ab
或者cd
進行選擇時,這個時候咱們就須要分支邏輯。具體示例代碼以下:
const reg = /ab|cd/; //表示選擇ab或者cd。爲何不是b和c呢?這個咱們在下一篇博客——進階篇中將會講述操做符優先級問題。
正則表達式除了捕獲字符,還能夠捕獲字符串中的位置。所謂的位置,指的就是兩個字符之間。好比'ab'
這個字符串,就有3個位置,分別位於a
前面、a
後面b
前面和b
後面。若是咱們將位置當成是一個空字符串''
,其實對於位置的匹配也能夠概括到對字符的匹配中。
匹配位置的方式也有很多,咱們來看下:
^
,匹配開頭,多行模式下匹配行開頭,即每行開頭都會被匹配。$
,匹配結尾,多行模式下匹配行結尾,即每行結尾都會被匹配。\b
,\w
與\W
之間的位置(\w
表示[0-9A-Za-z],而\W
就是\w
的補集),包括開頭結尾(即也包括\w
與^
之間的位置,和\w
與$
之間的位置)\B
,與\b
相反,\w
與\w
之間的位置,和\W
與\W
之間的位置,包括開頭結尾(相對的,即包括\W
與^
之間的位置,和\W
與$
之間的位置)(?=p)
,正向確定斷言。p
是一個子模式,匹配要在p
這個模式以前的位置(?!p)
,正向否認斷言。與(?=p)
相反,匹配不要在p
這個模式以前的位置上面說了這麼多,下面咱們經過一個示例來一下:
const reg1 = /^ab/; //對於字符串'abab'來講,只會匹配到開頭的'ab' const reg2 = /ab$/; //對於字符串'abab'來講,只會匹配到結尾的'ab' const reg3 = /\b/; //對於字符串'a b'來講,會匹配到'a'前面的位置、'a'和' '之間的位置、' '和'b'之間的位置、'b'後面的位置 const reg4 = /\B/; //對於字符串'aa bb[/來講,會匹配到'a'和'a'之間的位置、'b'和'b'之間的位置、'['後面的位置 const reg5 = /(?=a)/; //對於字符串'bac'來講,會匹配到'a'以前的位置 const reg6 = /(?!a)/; //對於字符串'bac'來講,會匹配到'b'以前的位置、'c'以前的位置以及'c'以後的位置
經過上面的例子,你們應該可以理解正則表達式在捕獲位置時候所發揮的做用。
在ES2018中,增長了反向確定斷言
和反向否認斷言
。具體格式以下:
(?<=p)
,反向確定斷言。p
是一個子模式,匹配要在p
模式以後的位置(?<!p)
,反向否認斷言。與(?<=p)
相反,匹配不要在p
模式以後的位置咱們經過一個具體的示例來看下:
const reg1 = /(?<=a)b/ //對於字符串'abb'來講,只會匹配到'a'和'b'之間的位置。 const reg2 = /(?<=a)b/ //對於字符串'abb'來講,會匹配到'b'和'b'之間的位置。
在正則表達式中,括號是一個功能很是多的操做符。本章咱們將會詳細介紹正則表達式中的括號的各類做用。
在正則表達式中,運算符操做也有優先級之分,以下例所示:
const reg1 = /ab|cd/; //匹配'ab'或者'cd' const reg2 = /a(b|c)d/;//匹配'a'後,匹配一個'b'或者'c',再匹配一個'd'
關於正則表達式優先級相關的討論,咱們在此就不作展開了,有興趣的同窗能夠閱讀個人後一篇關於正則表達式高級進階的文章。
若是咱們在正則表達式中,咱們須要獲取特定的匹配內容,那麼咱們就要用到捕獲組。捕獲組一般使用(p)
,其中p
是一個子模式,表示須要捕獲的內容。具體使用示例以下:
const reg = /a(bc)d/; let result = 'abcd'.match(reg); // 獲得的result[1]就是第一個捕獲組匹配的字符'ab'
可是,若是咱們在一些須要保證優先級的地方使用了小括號,可是又不想成爲捕獲組來干擾匹配,咱們應該怎麼辦呢?這個時候咱們就須要非捕獲組。咱們只須要在括號最開始加上一個?
便可。具體使用示例以下:
const reg = /a(?:bc)d/; let result = 'abcd'.match(reg); // 獲得的result沒有捕獲組
當咱們在正則表達式中須要使用前面捕獲組匹配的內容時,咱們可使用反向引用。這在匹配一些成對的字符如'
和"
等時很是有效。具體使用方式以下:
const reg = /(a)b\1/; //匹配字符'aba'
這裏須要注意的有三點:
\10
表示的含義爲第10個捕獲組,而不是第一個捕獲組加上一個字符0
。須要表示後者能夠用/(\1)0/
。即便是在第三種狀況下,轉移符優先級仍然高於字符順序。\
字符就會被當成一個轉移符而非反向引用。注:\2表示對2進行轉義的話,不一樣的瀏覽器對轉義後的結果是不同的。下圖是Chrome瀏覽器轉義後的結果
經過閱讀本文,你已經學到了正則表達式的最基礎的語法和使用規則。若是你想提升正則表達式的效率,加快正則表達式的閱讀和理解,能夠閱讀正則表達式系列第二篇文章。