用正規表示式找出不包含連續字串abc的單詞

2021-09-05 15:53:25 字數 1122 閱讀 2675

寫過一篇"

正規表示式30分鐘入門教程",有讀者問:

[^abc]表示不包含a、b、c中任意字元, 我想實現不包含字串abc應該如何寫表示式?
就我自己而言,這個問題最簡單的解決方法是使用程式語言的配合,找出那些包含abc的,剩下的就是不包含的了——懶人的風格。但我寫的是教程,讀者未必都有程式設計的基礎,有些只是使用一些工具從txt文件中抽取出一些資訊,所以要回答還是必須完全通過正規表示式來完成。

於是開啟了

regextester,開始試驗,先是試了使用

((?'test'abc)|.)*(?(test)(?!))(含意是:查詢abc,或任意的字元,如果找到了abc,就把它存入命名為test的組裡,到最後檢查test組裡是否有內容,如果有就匹配失敗,相關說明見

教程),結果是"abc","aabc","abcd","aa"都能通過測試,看來是到最後測試到test組存在後又回溯了,此解決方案不可行。

然後又試了

(.(?!abc))*(找出所有後面不是abc的字元),結果是"abc","abcd"通過測試,"aabc"則只擷取了後面的"abc",顯然不行。

那加強條件試試:

((?(找出所有前面和後面都不是abc的字元),結果是所有包含abc的字串都只擷取了裡面的"abc",不包含abc的則直接通過。

現在看來有點戲了,但是怎麼把那些內部包含abc的字串過濾掉呢?這個問題換句話說也就是怎麼匹配整體而不是部分呢?現在需要明確使用者的需求了:如果使用者想要找的是單詞,那就在表示式的兩端加上

\b,如果要找的是行,就加上

^和 $。由於使用者的問題沒有明確說明,我就當作是單詞吧。

於是等到了這樣的表示式:

\b((?,經過測試,這個表示式能匹配所有不包含abc的單詞,以及單詞abc。

怎麼排除單詞abc?經過一番思考,最後我認為判斷單詞是否以a開頭的方式最為方便:

\b(a(?!bc)|[^a](?!abc))((?(要麼以後面不是bc的a開頭,要麼不以a開頭,除了開頭後面所有的字元必須前面和後面都不是abc)。經過測試,完全滿足要求,bingo!

使用正規表示式查詢不包含連續字串abc的單詞,最終結果:

\b(a(?!bc)|[^a](?!abc))((?

\b((?!abc)\w)+\b

使用正規表示式找出不包含特定字串的條目概述

做日誌分析工作的經常需要跟成千上萬的日誌條目打交道,為了在龐大的資料量中找到特定模式的資料,常常需要編寫很多複雜的 正規表示式 例如列舉出日誌檔案中不包含某個特定字串的條目,找出不以某個特定字串打頭的條目,等等。正規表示式中有前瞻 lookahead 和後顧 lookbehind 的概念,這兩個術語...

使用正規表示式找出不包含特定字串的條目

概述 做日誌分析工作的經常需要跟成千上萬的日誌條目打交道,為了在龐大的資料量中找到特定模式的資料,常常需要編寫很多複雜的正規表示式。例如列舉出日誌檔案中不包含某個特定字串的條目,找出不以某個特定字串打頭的條目,等等。使用否定式前瞻 正規表示式中有前瞻 lookahead 和後顧 lookbehind...

使用正規表示式找出不包含特定字串的條目

做日誌分析工作的經常需要跟成千上萬的日誌條目打交道,為了在龐大的資料量中找到特定模式的資料,常常需要編寫很多複雜的正規表示式。例如列舉出日誌檔案中不包含某個特定字串的條目,找出不以某個特定字串打頭的條目,等等。正 則表示式中有前瞻 lookahead 和後顧 lookbehind 的概念,這兩個術語...