工做中,正則表達式用的可能不是不少,通常使用的時候網上都有現成的實例,不多缺少比較全面的理解。本文主要以匹配HTML標籤爲例,簡述下正則表達式經常使用的功能點。匹配HTML片斷以下:正則表達式
let str = ` <div id="app"> <div>21</div> <h1> <span>hello</span> <span>smile</span> </h1> <button>按鈕</button></div> `;
正則匹配本文查看結果主要用String.match(RegExp)方法,經常使用的正則匹配方法爲:RegExp.test(String),RegExp.exec(String)數組
一、正則表達式的聲明app
正則表達式的聲明方式和普通變量的聲明方式相似,通常狀況下有兩種,字面量和正則構造方法RegExp。以匹配span標籤爲例,匹配單個span標籤的正則以下:測試
// 字面量方式 let normalPattern = /span/ // 調用正則構造方法 let pattern = new RegExp('span')
2. 修飾符spa
上述的正則,在匹配測試文本是,輸出的結果是一個數組,只有一個元素span,若是我想匹配多個呢,這裏就要引入正則修飾符的概念了,經常使用的就是 i 和 g。code
i的含義是忽略大小寫,好比用/span/只能去匹配span字符串,SPAN匹配不了,若是想匹配SPAN,就要加上i修飾符orm
g的含義是global,全局查找,正則默認只匹配第一個符合條件的值,若是要全局匹配,就要加上g修飾符。blog
具體寫法以下:ip
// 字面量方式 let normalPattern = /span/ig // 調用正則構造方法 let pattern = new RegExp('span', 'ig')
3.字符類別字符串
以上匹配的文本都很是的基礎,假如我想匹配全部的HTML標籤,該怎麼寫呢?HTML標籤不少,無法一個個所有羅列出來,咱們可使用字符類別,進行快速的匹配。參考列表以下:
字符類別,在某種程度上來講,能夠理解爲一個字符集,如上述列表所示,\d是數字0-9的集合,若是咱們要匹配一段文本中全部的數字,能夠直接聲明以下正則:
let numberPattern = /\d/g
假如我要匹配全部的HTML標籤呢?在匹配一個文本以前,咱們須要先分析下HTML標籤規律,首先,HTML標籤和通常的XML標籤,都是以尖括號<大頭,以尖括號>結尾,其次,中間只能是英文字母或者數字,最後,數字或字母可能出現一次或者屢次。寫正則的第一要素是先概括總結,總結出規律才能去分析正則的寫法。正則表達式本質上也是一種規律的解釋文本。從咱們總結的規律中,咱們能夠按照以下寫法:
let matchTags = /<\w+>/g
匹配結果以下:
[ '<div>', '<h1>', '<span>', '<span>', '<button>' ]
\w表明數字或者字母,+表明匹配一次或者屢次,g表明全局匹配。咱們在匹配文本的時候,一種規律有時候不可能只用一次,正則表達式提供了豐富的數量詞語法,可以知足咱們絕大多數要求,下面的章節會有介紹。
咱們看到,咱們匹配的HTML標籤只是前面的標籤,並無後面的閉合標籤,咱們如何匹配閉合標籤呢?閉合標籤比普通的標籤多了一個斜槓/,若是咱們單純的寫/,是不能夠的,你們可能意識到,正則表達式的字面量寫法是兩個斜槓/包起來的,若是咱們直接寫,會有衝突,這時候,咱們須要藉助轉義字符反斜槓\進行轉義便可,一些與正則表達式衝突的,都須要用轉義字符進行轉義,好比特殊字符(),[],還有是一些具備特殊意義的集合,\w,\d....
匹配閉合標籤的正則以下:
let matchCloseTags = /<\/\w+>/g
匹配結果:
[ '</div>', '</span>', '</span>', '</h1>', '</button>', '</div>' ]
4.數量詞
在字符類中,咱們用到了數量詞+,表明匹配一次或屢次。正則表達式數量詞遠遠不止這些,具體列表以下所示:
舉個例子,假如我要匹配HTML片斷中的h標籤,咱們都知道h標籤的基本規則爲只有一個字母和數字,從上述咱們能夠得出,咱們能夠用數量詞{n},正則表達式以下:
let matchH = /<h{1}\d{1}>/g
匹配結果:
[ '<h1>' ]
在這裏,咱們要記住兩個個數量詞,x*?和x+?,這個是最小匹配原則。假如如今咱們要匹配第一個span閉合標籤和文本,即<span>hello</span>,若是咱們按照正常思路去寫,以<span>開頭,</span>結尾,中間是任意字符,正則表達式實現以下所示:
let matchSpan = /<span>(\S|\s)+<\/span>/g
匹配結果可能和咱們預想的不大同樣,實際上匹配結果只有一個,以下所示:
[ '<span>hello</span>\n <span>smile</span>' ]
正則默認的會全文匹配,並不會按照最小匹配原則,即找到符合條件的文本就返回,他會最大程度的去匹配符合條件的文本。若是咱們要分別匹配兩段span標籤,咱們就須要用到最小匹配原則的數量詞,具體以下:
let matchSpan = /<span>(\S|\s)*?<\/span>/g
let matchSpan2 = /<span>(\S|\s)+?<\/span>/g
文本匹配結果:
[ '<span>hello</span>', '<span>smile</span>' ]
5.集合
正則表達式中,集合使用也比較多,語法比較簡單,全部須要匹配的文本依次放在中括號[]中,好比若是你想匹配abc三個字母,pattern=/[abc]/,若是不想匹配abc,那就是pattern=[^abc],若是匹配數字,那就是/[0-9]/,-表明一個連續的集合,字母就是[a-zA-Z]
6.邊界
邊界最簡單的用法,^表明匹配輸入的開始,$表明匹配輸入的結束。
7.分組
假如如今有這樣一個需求,須要匹配span標籤裏的文本,而不須要span標籤, 此時可能會用到分組,從字面意思上來講,分組就是把規則分類。分組的語法比較簡單,就是小括號()。轉換爲正則的語法以下:
let matchSpanText = /(<span>)(\S+)+?(<\/span>)/
let result = str.match(matchSpanText)
匹配結果以下圖所示:
從上圖能夠看出,匹配結果數組result長度爲4,第一部爲匹配的結果,第二部分爲(span)匹配的結果,第三部分爲(\S+)匹配的結果,第四部分爲(</span>)匹配的結果,若是咱們要拿純文本,直接去arr[2]便可。咱們也能得出一個結論,所謂分組,其實就是普通的正則匹配加上分組條件的匹配集合。
8.斷言
斷言是個好東西,可以解決許多比較棘手的問題,好比上面的例子,我想拿兩個標籤中間的文本,採用分組去取,是能夠實現,可是就看每次都要拿匹配結果的第三個數組,有點不爽,怎麼辦呢,斷言能夠幫你解決這個煩惱,匹配的結果直接是文本。斷言的基本規則以下:
從基本規則中,咱們能夠從字面上得出,斷言能夠設置一個文本先後的匹配規則,咱們能夠將匹配標籤中間的文本規則改造以下:
let matchSpanTextDescribe = /(?<=<span>)(\S+)+?(?=<\/span>)/g
let result = str.match(matchSpanTextDescribe)
匹配結果以下:
參考資料:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/RegExp#boundaries