正規表示式匹配不包含某些字串的技巧

2022-01-10 11:13:21 字數 1627 閱讀 1378

經常我們會遇到想找出不包含某個字串的文字,程式設計師最容易想到的是在正規表示式裡使用,^(hede)來過濾」hede」字串,但這種寫法是錯誤的。我們可以這樣寫:[^hede],但這樣的正規表示式完全是另外乙個意思,它的意思是字串裡不能包含『h',『e',『d'三個但字元。那什麼樣的正規表示式能過濾出不包含完整「hello」字串的資訊呢?

事實上,說正規表示式裡不支援逆向匹配並不是百分之百的正確。就像這個問題,我們就可以使用否定式查詢來模擬出逆向匹配,從而解決我們的問題:

^((?!hede).)*$
上面這個表示式就能過濾出不包含『hede'字串的資訊。我上面也說了,這種寫法並不是正規表示式「擅長」的用法,但它是可以這樣用的。

解釋

乙個字串是由n個字元組成的。在每個字元之前和之後,都有乙個空字元。這樣,乙個由n個字元組成的字串就有n+1個空字串。我們來看一下「abhedecd」這個字串:

所有的e編號的位置都是空字元。表示式(?!hede).會往前查詢,看看前面是不是沒有「hede」字串,如果沒有(是其它字元),那麼.(點號)就會匹配這些其它字元。這種正規表示式的「查詢」也叫做「zero-width-assertions」(零寬度斷言),因為它不會捕獲任何的字元,只是判斷。

在上面的例子裡,每個空字元都會檢查其前面的字串是否不是『hede',如果不是,這.(點號)就是匹配捕捉這個字元。表示式(?!hede).只執行一次,所以,我們將這個表示式用括號包裹成組(group),然後用*(星號)修飾——匹配0次或多次:

((?!hede).)*。
你可以理解,正規表示式((?!hede).)*匹配字串"abhedecd"的結果false,因為在e3位置,(?!hede)匹配不合格,它之前有"hede"字串,也就是包含了指定的字串。

在正規表示式裡, ?! 是否定式向前查詢,它幫我們解決了字串「不包含」匹配的問題。

以下是一些補充:

分享下php生成隨機數的三種方法,生成1-10之間的不重複隨機數,php生成不重複隨機數的例子,需要的朋友參考下。

在hacker news上看到regex golf,幾道很有趣的正規表示式的題,有的需要用到不匹配這種匹配,比如需要匹配不包含某個單詞的串。

開始正題之前,先來看看正規表示式的語法:

正規表示式中有(?=a)和(?!a)來表示我們是否需要匹配某個東西。

所以,有需要不匹配某樣內容時,就可以用(?!a)了。比如要匹配不含hello的字串就可以這樣寫。

^(?!.*hello)
這裡.*用來表示hello之前可能有其他的字元,為什麼還要加^呢,因為如果不加的話,可能匹配到h之後的這個位置上了。

現在就可以解決regex golf上的abba這道題了。

這道題是去匹配不含abba這種形式的單詞,比如abba,anallagmatic就不應該匹配上。

正規表示式**:

^(?!.*(.)(.)\2\1)
然後利用不匹配,還可以解決prime這道題,這道題匹配有素數個x的串,先看正則。

^(?!(xx+)\1+$)
(xx+)是匹配2個及2個以上的x,(xx+)\1+就是匹配重複出現2個及以上的串,所以(xx+)\1+就表示了那些非素數的串,那麼素數串就是除去這些非素數串,即是以上的正規表示式了。

不包含某字串的字串匹配 正規表示式

判斷乙個字串中是否含有另一字串,有很多方法,如下 1.常見函式 strstr str,abc 2.正則匹配 preg match abc is str 但是要匹配乙個字串中,不包含某字串,用正則就比較麻煩了。1.如果不用正則如下就可以解決問題 strstr str,abc 2.但是用正則呢,就只有這...

不包含字串abc的正規表示式

abc 表示不包含a b c中任意字元,我想實現不包含字串abc應該如何寫表示式?最簡潔的寫法 b abc w b 匹配由字母或數字或下劃線或漢字組成的字串,但字串中不能出現abc 解釋 b 匹配單詞的開始或結束 exp 零寬負向先行斷言,只會匹配字尾exp不存在的位置 w 匹配字母或數字或下劃線或...

正規表示式匹配字串

正規表示式用於字串處理 表單驗證等場合,實用高效。現將一些常用的表示式收集於此,以備不時之需。匹配中文字元的正規表示式 u4e00 u9fa5 評注 匹配中文還真是個頭疼的事,有了這個表示式就好辦了 匹配雙位元組字元 包括漢字在內 x00 xff 評注 可以用來計算字串的長度 乙個雙位元組字元長度計...