JS 正則中的命名捕獲分組

2022-02-09 01:40:35 字數 2025 閱讀 5915

假設你在一段陌生的**中看到這樣乙個函式: 

function

tolocaldate(date) )-(\d)-(\d)/, "$2-$1-$3")

}

單看這個函式你能知道它是想把「日-月-年」替換成「月-日-年」,還是反過來?匿名捕獲分組沒法做到這一點,那就該命名捕獲分組上場了:

function

tolocaldate(date))-(?\d)-(?\d)/, "$-$-$")

}

俗話說的好,「乙個好的變數名賽過一行注釋」,命名捕獲分組很大的乙個作用就是它能起到注釋的作用。

另外,命名捕獲分組還有乙個好處,那就是假如你在修改乙個正則時,在已有分組的左邊引入了新的分組,那麼你還得記得更新已有的反向引用的數字。比如將 (foo)\1 改成了 (bar)(foo)\1,那你得把原來的 \1 改成 \2,replace() 方法的第二個引數裡的 $1 也同樣得改,用命名分組不會有這個問題。

命名捕獲分組自身的語法是 (?...),比普通的分組多了乙個 ?字樣,其中 name 的起法就和你平時起變數名一樣即可(不過在這裡關鍵字也可用)。

反向引用乙個命名分組的語法是 \k,注意命名分組同樣可以通過數字索引來反向引用,比如:

/(?a)\k\1/.test("aaa") //

true

在 replace() 方法的替換字串中反向引用是用 $:

"abc".replace(/(?a)/, "$-") //

"a-bc",同樣 $1 仍然可用

總結一下就是,和命名分組相關的有三種語法,分別是 ?、\k、$,相同點是都用尖括號包裹著分組名。

const groups = "04-25-2017".match(/(?\d)-(?\d)-(?\d)/).groups //

const = groups

exec() 和 match() 方法返回的匹配結果陣列上多了乙個 groups 屬性,裡面存放著每個命名分組的名稱以及它們匹配到的值,利用 es6 的解構語法,可以方便的提取出想要的字段。注意這個 groups 屬性只有在當前正則裡至少存在乙個命名分組的前提下才會存在,比如:

/(\d)-(\d)-(\d)/.exec("04-25-2017").groups //

undefined,因為沒有命名分組

replacement 是字串的情況上面已經舉過例子了,這裡主要講它是函式的情況:

"04-25-2017".replace(/(?\d)-(?\d)-(?\d)/, (...args) => =groups

return `$-$-$`

}) //

"25-04-2017"

也就是說,在實參列表的最末尾,多傳了乙個 groups 物件。同樣,如果正則裡沒有命名分組,這個引數不會存在。

分組名不能有重複項:

/(?a)(?b)/ //

syntaxerror: duplicate capture group name

反向引用乙個不存在的分組名:

/\k/u //

syntaxerror: invalid named capture referenced

/\k/.test("k") // true,

非 unicode 下為了向後相容,k 前面的 \ 會被丟棄

在 reaplce() 方法的替換字串中引用乙個不存在的分組:

"abc".replace(/(?.*)/, "$") //

syntaxerror: invalid replacement string

"abc".replace(/(.*)/, "$") //

"$",不包含命名分組時會向後相容

v8 目前已經完全實現了命名捕獲分組的提案 

命名分組雖然帶來了一些好處,但我個人覺得,正則越長越難讀懂,尤其增加的長度是一堆小括號和尖括號。在可讀性上,命名分組也許會起到反作用,尤其對正則苦手來說。 

正則 分組 捕獲 總

分組 捕獲 魔芋 01,小括號 又稱為圓括號 會產生子表示式 又稱為分組,子串 可以在正則中 1,2來引用子表示式匹配的文字值。這些子表示式會被臨時緩衝區快取起來。所捕獲的每個子匹配都按照在正規表示式模式中從左到右出現的順序儲存。緩衝區編號從 1 開始,最多可儲存 99 個捕獲的子表示式。每個緩衝區...

筆記 正則命名捕獲

參考 命名捕獲分組 總結 123 match 1 2 3 結果中返回乙個滿足條件的字串,然後根據括號對這個字串進行拆分,乙個括號就相當於push 一下 這時候無意義的下標對於後期在失去注釋,或無意義 不全的注釋的狀態下維護,會讓我們的維護增加難度 所以在括號內容前以?名 的形式增加乙個申明,例如 1...

js正規表示式分組捕獲

const reg reg.test 比如去掉 aaa 中的中括號 這裡只是舉個例,可以這樣來處理更複雜的模板字串 const reg a za z let str aaa while reg.test str console.log str str 這裡的 1就是 1 const reg a z ...