負向零寬斷言

2022-03-31 00:13:31 字數 1035 閱讀 4684

前面我們提到過怎麼查詢不是某個字元或不在某個字元類裡的字元的方法(反義)。但是如果我們只是想要確保某個字元沒有出現,但並不想去匹配它時怎麼辦?例如,如果我們想查詢這樣的單詞--它裡面出現了字母q,但是q後面跟的不是字母u,我們可以嘗試這樣:

\b\w*q[^u]\w*\b匹配包含後面不是字母u的字母q的單詞。但是如果多做測試(或者你思維足夠敏銳,直接就觀察出來了),你會發現,如果q出現在單詞的結尾的話,像iraq,benq,這個表示式就會出錯。這是因為[^u]總要匹配乙個字元,所以如果q是單詞的最後乙個字元的話,後面的[^u]將會匹配q後面的單詞分隔符(可能是空格,或者是句號或其它的什麼),後面的\w*\b將會匹配下乙個單詞,於是\b\w*q[^u]\w*\b就能匹配整個iraq fighting。負向零寬斷言能解決這樣的問題,因為它只匹配乙個位置,並不消費任何字元。現在,我們可以這樣來解決這個問題:\b\w*q(?!u)\w*\b。

零寬度負**先行斷言(?!exp),斷言此位置的後面不能匹配表示式exp。例如:\d(?!\d)匹配三位數字,而且這三位數字的後面不能是數字;\b((?!abc)\w)+\b匹配不包含連續字串abc的單詞。

同理,我們可以用(?零寬度負回顧後發斷言來斷言此位置的前面不能匹配表示式exp:(?前面不是小寫字母的七位數字。

請詳細分析表示式(?<=<(\w+)>).*(?=<\/\1>),這個表示式最能表現零寬斷言的真正用途。

乙個更複雜的例子:(?<=<(\w+)>).*(?=<\/\1>)匹配不包含屬性的簡單html標籤內裡的內容。(?<=<(\w+)>)指定了這樣的字首:被尖括號括起來的單詞(比如可能是),然後是.*(任意的字串),最後是乙個字尾(?=<\/\1>)。注意字尾裡的\/,它用到了前面提過的字元轉義;\1則是乙個反向引用,引用的正是捕獲的第一組,前面的(\w+)匹配的內容,這樣如果字首實際上是的話,字尾就是了。整個表示式匹配的是之間的內容(再次提醒,不包括字首和字尾本身)。

負向零寬斷言

如果我們只是想要確保某個字元沒有出現,但並不想去匹配它時怎麼辦?例如,如果我們想查詢這樣的單詞 它裡面出現了字母q,但是q後面跟的不是字母u,我們可以嘗試這樣 b w q u w b 匹配包含後面不是字母u的字母q的單詞 但是如果多做測試 或者你思維足夠敏銳,直接就觀察出來了 你會發現,如果q出現在...

grep 零寬斷言

參考參考二 算是正則環視的乙個簡單應用吧。前兩天因為第三方遊戲伺服器掉線,導致大量使用者同時登入我的伺服器,將伺服器負載瞬間提高到200 如此恐怖的數字讓我不得不考慮增加伺服器來抵抗問題重現,然而我的伺服器平時負載都很低,0.1都不到,增加伺服器來應付這樣短暫的風暴未免太過於浪費,於是我決定從日誌下...

vim 零寬斷言

vim 中使用零寬度斷言,包括 符號vim符號 描述示例 vim示例 正先行斷言 存在 foo bar foo bar 負先行斷言 排除 foo bar foo bar 正後發斷言 存在 foo bar foo bar?負後發斷言 排除 foo 先行斷言和後發斷言都屬於非捕獲簇 不捕獲文字 也不針對...