淺析正則表達式用法:匹配分組


一、匹配分組

字符 功能
| 匹配左右任意一個表達式
(ab) 將括號中的字符作為一個分組
\num 引用分組num匹配到的字符串
(?<name>) 分組起別名
(\k<name>) 引用別名為name分組匹配到的字符串

 

 

 

 

 

 

 

 

1、|

  需求:匹配出0-100之間的數字

  分析:首先我們明確這之間的數字包含0,兩位數,100,也就是一位,兩位,三位的可能都有,鑒於一位0,三位100都是單獨數字,我們可以使用 | 來連接(相當於or),着重考慮一位數[1-9],兩位數[10-99],分析其特征,這里第一位數必須為[1-9],第二位[0-9]都可以(\d可以表示),對於一位數[1-9]的第二位可以不出現(?可以表示),再加個結尾$,防止234匹配到23的情況。因此正則表達式為:

/^[1-9]\d?$|0$|100$/

2、(ab) 將括號中的字符作為一個分組

  需求 :在網頁開發或者爬蟲時,處理對象是HTML,比如某網頁HTML中有這樣的內容:<h1>我的CSDN</h1>。那么我該如何把<h1>content</h1>中的content提取出來呢?

  分析:提取的內容用 () 括起來就可以了。<h1> </h1>是固定標簽,這是不變的,變的是content,因此我的正則表達式可表示為:

/<h1>(.*)<\/h1>/
let res = /<h1>(.*)<\/h1>/
'<h1>我的博客</h1>'.match(res) // (2) ["<h1>我的博客</h1>", "我的博客", index: 0, input: "<h1>我的博客</h1>", groups: undefined] // 0: "<h1>我的博客</h1>" // 1: "我的博客" // groups: undefined // index: 0 // input: "<h1>我的博客</h1>" // length: 2

  我們看看兩個括號的情況:

let res = /<span>(\d+)<\/span><h1>(.*)<\/h1>/
'<span>1234</span><h1>我的CSDN</h1>'.match(res) // (3) ["<span>1234</span><h1>我的CSDN</h1>", "1234", "我的CSDN", 
index: 0, input: "<span>1234</span><h1>我的CSDN</h1>", groups: undefined]

  獲取元素為3個的數組,就不多展開了,根據數組內容就可以很方便的獲取到需要的content的內容。

  所以說,() 在網頁開發或爬蟲里還是挺重要的。

3、\num 引用分組num匹配到的字符串

  需求 :還是以網頁為例,比如判斷某網頁HTML格式是否正確,其中有內容:<html><h1>我的CSDN</h1></html>。這時,我們不關心里面的內容,我們關心的是格式是否正確,就是說這樣的格式:<html>標簽必須有</html>結束,<h1>標簽必須有</h1>結束。

  分析:這個時候像html和h1才是關鍵內容,如果我們把這些用()保存起來,並且在后面一定對應這些內容,就能保證標簽的配對,而\num就是解決這樣的問題的

  首先我們看個錯誤的樣例:

let res = /<.+><.+>.+<\/.+><\/.+>/
'<html><h1>my csdn</h1></html>'.match(res) // ["<html><h1>my csdn</h1></html>", index: 0, input: "<html><h1>my csdn</h1></html>", groups: undefined]
let res = /<.+><.+>.+<\/.+><\/.+>/
'<html><h1>my csdn</h1></ht>'.match(res) // ["<html><h1>my csdn</h1></ht>", index: 0, input: "<html><h1>my csdn</h1></ht>", groups: undefined]

  我們把/html改成了/ht 明顯格式不對,但還是匹配了。我們應該讓第一個<tag>的內容出現在最后</tag>中,因此需要保存起來,用()括起來

  正確的方法:我們應該把<tag>用()括起來,變成<(tag)>,因此正則表達式為:

/<(.+)><(.+)>.+<\/\2><\/\1>/
let res = /<(.+)><(.+)>.+<\/\2><\/\1>/
'<html><h1>my csdn</h1></ht>'.match(res) // null
let res = /<(.+)><(.+)>.+<\/\2><\/\1>/
'<html><h1>my csdn</h1></html>'.match(res) // (3) ["<html><h1>my csdn</h1></html>", "html", "h1", 
index: 0, input: "<html><h1>my csdn</h1></html>", groups: undefined]

  解釋下,這個\2 和 \1。這個就是對應(tag)的分組,可以通過下面的index內容獲取。上面正確的標簽,那么 \1指的就是html,\2 指的就是h1

4、(?<name>) 分組起別名 和 (\k<name>) 引用別名

  需求 :上面我們已經可以通過\num取得對應的內容用以限定前面的內容,但是如果我有100個括號,那我們就只能數括號的索引index,然后把用\index取得么?答案:當然不是。

  分析:這時候取別名(?<name>)就派上用場了,它通過對括號里的內容取別名,然后通過(\k<name>)就可以取得對應的內容,你只要記住別名name,這樣就不用去數括號,記索引了。是不是很人性化......

  這個語法是:在括號里面同時寫上取的別名,以 ?<name> 命名;引用時以 \k<name> 取得別名,所以該正則表達式為:

/<(?<key1>.+)><(?<key2>.+)>.+<\/(\k<key2>)><\/(\k<key1>)>/
let res1 = /<(?<key1>.+)><(?<key2>.+)>.+<\/(\k<key2>)><\/(\k<key1>)>/
'<html><h1>my csdn</h1></html>'.match(res1) // (5) ["<html><h1>my csdn</h1></html>", "html", "h1", "h1", "html", 
index: 0, input: "<html><h1>my csdn</h1></html>", groups: {…}]
0: "<html><h1>my csdn</h1></html>" 1: "html" 2: "h1" 3: "h1" 4: "html" groups: key1: "html" key2: "h1" index: 0 input: "<html><h1>my csdn</h1></html>" length: 5 __proto__: Array(0)

  關於正則分組別名,詳細的可以看之前總結的這篇博客:JavaScript 正則命名分組


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM