一個斷言就是一個對當前匹配位置以前或以後的字符的測試, 它不會實際消耗任何字符。簡單的斷言代碼有\b、\B、 \A、 \Z、\z、 ^、$ 等等。 更加複雜的斷言以子組的方式編碼。 它有兩種類型: 前瞻斷言(從當前位置向前測試)和後瞻斷言(從當前位置向後測試)。 javascript
一個斷言子組的匹配仍是經過普通方式進行的, 不一樣在於它不會致使當前的匹配點發生改變。 前瞻斷言中的正面斷言(斷言此匹配爲真)以 」(?=」 開始,消極斷言以 」(?!」 開頭。好比, \w+(?=;) 匹配一個單詞緊跟着一個分號可是匹配結果不會包含分號, foo(?!bar) 匹配全部後面沒有緊跟 」bar」 的 」foo」 字符串。 注意一個相似的模式 (?!foo)bar, 它不能用於查找以前出現全部不是 」foo」 的 」bar」 匹配, 它會查找到任意的 」bar」 出現的狀況, 由於 (?!foo) 這個斷言在接下來三個字符時 」bar」 的時候是永遠都 TRUE 的。 前瞻斷言須要達到的就是這樣的效果。 java
後瞻斷言中的正面斷言以」(?<=」開始, 消極斷言以」(?<!」開始。好比, (?<!foo)bar 用於查找任何前面不是 」foo」 的 」bar」。 後瞻斷言的內容被嚴格限制爲只能用於匹配定長字符串。可是,若是有多個可選分支, 它們不須要擁有相同的長度。好比 (?<=bullock|donkey) 是容許的, 可是 (?<!dogs?|cats?) 將會引起一個編譯期的錯誤。在最上級分支能夠匹配不一樣長度的字符串是容許的。 相比較於 perl 5.005 而言,它會要求多個分支使用相同長度的字符串匹配。 (?<=ab(c|de)) 這樣的斷言是不容許的, 由於它單個的頂級分支能夠匹配兩個不一樣的長度, 可是它能夠接受使用兩個頂級分支的寫法 (?<=abc|abde) 這樣的斷言實現, 對於每一個可選分支,暫時將當前位置移動到嘗試匹配的當前位置以前的固定寬度處。 若是在當前沒有足夠的字符就視爲匹配失敗。後瞻斷言與一次性子組結合使用能夠用來匹配字符串結尾; 一個例子就是在一次性子組上給出字符串結尾。 測試
多個斷言(任意順序)能夠同時出現。 好比 (?<=\d{3})(?<!999)foo 匹配前面有三個數字但不是 」999」 的字符串 」foo」。注意, 每一個斷言獨立應用到對目標字符串該點的匹配。 首先它會檢查前面的三位都是數字, 而後檢查這三位不是 」999」。 這個模式不能匹配 」foo」 前面有三位數字而後緊跟 3 位非 999 共 6 個字符的字符串,好比, 它不匹配 」123abcfoo」。 匹配 」123abcfoo」 這個字符串的模式能夠是(?<=\d{3}…)(?<!999)foo。 編碼
這種狀況下,第一個斷言查看(當前匹配點)前面的 6 個字符,檢查前三個是數字, 而後第二個斷言檢查(當前匹配點)前三個字符不是 」999」。 spa
斷言能夠以任意複雜度嵌套。 好比 (?<=(?<!foo)bar)baz 匹配前面有 」bar」 可是 」bar」 前面沒有 」foo」 的 」baz」。 另一個模式 (?<=\d{3}…(?<!999))foo 則匹配前面有三個數字字符緊跟 3 個不是 999 的任意字符的 」foo」。 ip
斷言子組時非捕獲子組,而且不能用量詞修飾, 由於對同一件事作屢次斷言是沒有意義的.若是全部的斷言都包含一個捕獲子組, 那麼爲了在整個模式中捕獲子組計數的目的,它們都會被計算在內。然而, 子字符串的捕獲僅能夠用於正面斷言,由於對於消極的斷言是沒有意義的。 字符串
將斷言計算在內,能夠擁有的最大子組數量是 200 個。 編譯
javascript不支持後瞻斷言。 perl