使用正規表示法分組

Julypenguin
4 min readMay 17, 2020

--

分組就是透過小括號的方式來分隔,小括號內放入想搜尋的相關字詞排序就可以了,但有小括號和沒小括號使用起來會有差別嗎?

如果要搜尋下面的 HTML 標籤

const tag = '<html><head><title></title></head><body></body></html>'

如果直接使用 /<.*>/ 來搜尋,它就會配對最左邊的 <,.* 恨搜尋所有的字元,遇到最右邊的 > 結束,所以就會搜尋到完整的字串

const reg = /<.*>/
console.log(tag.match(reg)) // "<html><head><title></title></head><body></body></html>"

但我們可能是想搜尋到每一個標籤,而不是一整串,這時可能就會思考是不是使用 /<.*?>/g 來比對,這個時候有沒有使用小括號結果是一樣的

const reg = /<.*?>/g
const regGroup = /(<.*?>)/g
console.log(tag.match(reg)) // ["<html>", "<head>", "<title>", "</title>", "</head>", "<body>", "</body>", "</html>"]
console.log(tag.match(regGroup)) // 相同

但如果是比對固定文字的重複序列的話,就可以使用分組來簡單做到許多事情,可以使用 {} 來比對特定次數,比如說:

  • {3} 就是連續比對 3 次
  • {1 , 4} 就是最多連續比對 4 次
  • {0, } 就是比對任意次數
  • ? 就是最多比對 1 次
  • + 就是最少比對 1 次

而且也可以使用 "\" + 數字 的方式來參考括號內的子運算式,比如說 \1 就是參考由左至右第一個括號的子運算式, \2 就是參考第二個括號的子運算式

const text = 'abcdef-abcdef-abcdef-abcdef-abcdef'
let reg = /(abcdef-?)*/
console.log(text.match(reg)) // 'abcdef-abcdef-abcdef-abcdef-abcdef'
reg = /(abcdef-?){3}/
console.log(text.match(reg)) // 'abcdef-abcdef-abcdef-'
reg = /(abcdef-?){1,4}/
console.log(text.match(reg)) // 'abcdef-abcdef-abcdef-abcdef-'
reg = /(abcdef-?){0,}/
console.log(text.match(reg)) // 'abcdef-abcdef-abcdef-abcdef-abcdef'
reg = /(abcdef-?)?/
console.log(text.match(reg)) // 'abcdef-'
reg = /(abcdef-?)+/
console.log(text.match(reg)) // 'abcdef-abcdef-abcdef-abcdef-abcdef'
reg = /(abcdef-?)\1/
console.log(text.match(reg)) // abcdef-abcdef-

不過在使用 \1 之類的方法要注意子運算式的參考並不是指那個子運算式的模式,而是與那個模式相符合的文字,比如說

let tag = '<h1>title<h1><p>text<p>'const reg = /(<\/?\w+>).*\1/g
console.log(tag.match(reg)) // ["<h1>title<h1>", "<p>text<p>"]
tag = '<h1>title</h1><p>text</p>'
console.log(tag.match(reg)) // null

雖然子運算式可以比對 <h1> 也可以比對 </h1> ,但是 \1 是參考子運算式符合的文字,所以能不到找到就要看文字有沒有相符合的了

--

--

No responses yet