正則匹配中,除了文本的匹配外,還有位置匹配。
因爲位置匹配不會匹配任何實際的文本,只是匹配文本中的位置,所以也稱爲錨點(Anchors)、零長度斷言 或者 零寬斷言 (Zero-Width Assertions)。
結合這幾個名字,這個概念的含義已經很明顯。
零寬斷言是一種零寬度的匹配,它匹配的內容不會保存到匹配結果中,也不會佔用index寬度,最終匹配的結果只是一個位置
簡單的說,它用於查找在某些內容之前或之後的東西(但返回結果並不包括這些內容)
JavaScript提供瞭如下的零寬斷言:
零寬斷言 意義
^ 匹配輸入的開始。
$ 匹配輸入的結束。
\b 匹配一個詞的邊界。
\B 匹配一個非單詞邊界。
(?=p) 肯定順序環視
(?!p) 否定順序環視
(?<=p) 肯定逆序環視
(?<!p) 否定逆序環視
js的負向零寬斷言是ES2018才支持的,同時支持的還有,命名分組和dotAll(.能匹配換行符)
Lookbehind assertion: (?<=...), (?<!...) (負向零寬斷言) chrome 62 safari 16.4
function getPrice(label) { return /(?<=\$)\d+(?:\.\d*)?/.exec(label)?.[0]; } getPrice("$10.53"); // "10.53" getPrice("10.53"); // undefined
safari又拉胯,對於要兼容safari的情況,可以使用折中方案
1. 字符串和正則同時反轉,然後匹配
2. 使用前置可空組判斷(推薦,看起來簡單一些)
前端匹配的字符串用一個組保存,通過判斷這個組是否存在來處理
匹配所有前面不是ba的ll
var newString = "Fall ball bill balll llama".replace(/(ba)?ll/g, function($0,$1){ return $1 ? $0 : "[match]";}); // Fa[match] ball bi[match] balll [match]ama
ES2018同時支持的還有,命名分組和dotAll(.能匹配換行符)
Named capture groups(命名分組捕獲) chrome 64 safari 11.1
const t = '2020-01-23'.match(/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/)
console.log(t.groups.year)
console.log(t.groups.month)
console.log(t.groups.day)
參考: