2008-10-02 999 views
78

我使用的是RegexBuddy,但我無論如何都遇到了這個問題:\如何與regex「反向匹配」?

我正在逐行處理一個文件。我建立了一個「線條模型」來匹配我想要的。

現在我想要做的逆匹配...即我想匹配,其中有6個字母串線,但只有這六個字母安德烈,我應該怎麼辦那?


編輯:我會寫一個使用此正則表達式的程序,我還不知道如果在Python或PHP中,我第一次做這個事情,瞭解一些正則表達式:)有不同類型的行,我想用正則表達式來選擇我感興趣的類型。一旦我得到了這些行,我必須應用其他過濾器只是爲了不匹配已知的值,我需要所有其他的,而不是那。 (?!不想要的)工作得很好,謝謝。 :-)

我希望這個澄清的問題:)

+0

這實際上聽起來像你可能會做得更好,給我們更多關於你在做什麼的信息,並看看有人能提供一種替代解決方案。通常,嘗試通過構建匹配每行的正則表達式來解析整個文件是一個相當複雜的路徑:) – Dan 2008-10-02 20:33:22

回答

47
(?!Andrea).{6} 

假設你的正則表達式引擎支持的負面向前看符號..

編輯:..或者也許你寧願在場所使用[A-Za-z]{6}.{6}

編輯(再次):請注意,lookaheads和lookbeheads通常不是正確的方式來「反轉」正則表達式匹配。正則表達式並不是用來做負面匹配的,他們把它留給你使用它們的任何語言。

+0

您需要添加@Vinko Vrsalovic使用的^,以便它不匹配「ndrea \ n」 – bdukes 2008-10-02 20:34:47

+2

。與默認情況下不匹配\ n(某些語言[例如Perl]允許您打開該行爲,但默認情況下匹配所有內容但是\ n)。 – Dan 2008-10-02 20:36:37

+1

(另外,OP從未提到過線必須在線的開始處出現) – Dan 2008-10-02 20:37:11

5

Negative lookahead assertion

(?!Andrea) 

這不正是一個倒置的比賽,但它是你可以直接用正則表達式做的最好的。不是所有的平臺都支持它們。

10

你在用什麼語言?正則表達式實現的功能和語法對此很重要。

您可以使用預見。使用Python作爲例子

import re 

not_andrea = re.compile('(?!Andrea)\w{6}', re.IGNORECASE) 

要打破下來:

(?!安德烈)手段 '匹配,如果未來6個字符不是 「安德烈」';如果是的話

\ w表示一個「單詞字符」 - 字母數字字符。這相當於類[a-zA-Z0-9_]

\ w {6}意味着正好6個單詞字符。

re.IGNORECASE意味着你將排除「安德烈」,「安德烈」,「安德烈」 ......

另一種方法是使用你的程序邏輯 - 使用不匹配安德烈所有線路,並把它們通過第二個正則表達式來檢查6個字符。或者首先檢查至少6個單詞字符,然後檢查它是否與Andrea不匹配。

-3

在Perl中,你可以做

過程($線),如果($線=〜/安德烈/!);

4

如果你想在RegexBuddy中做到這一點,有兩種方法可以得到不匹配正則表達式的所有行的列表。

在測試面板的工具欄上,將測試範圍設置爲「逐行」。當你這樣做時,列出所有沒有匹配的行將顯示在同一工具欄上的全部列表按鈕下。 (如果您沒有看到全部列表按鈕,請單擊主工具欄上的匹配按鈕。)

在GREP面板上,您可以打開「基於行」和「反轉結果」複選框以獲取您正在掃描的文件中的不匹配行的列表。

3

(?!在實踐中是有用的。 雖然嚴格來說,展望未來是正確的數學定義表達。

您可以手動編寫反轉正則表達式。

這裏是a program自動計算結果。 它的結果是機器生成的,通常比手寫的要複雜得多。 但結果起作用。

10

更新與反饋Alan Moore

在PCRE和類似的變種,實際上就可以創建符合不包含任何有價值的行正則表達式:

^(?:(?!Andrea).)*$ 

這就是所謂的tempered greedy token。缺點是它表現不佳。

0

我剛剛想出了這個方法,這可能是硬件密集的,但它的工作:

可以更換成空字符串匹配的正則表達式所有字符。

這是一個oneliner:

notMatched = re.sub(regex, "", string)

我用這個,因爲我被迫使用一個非常複雜的正則表達式,無法弄清楚如何反轉的每一個部分。

這將只返回字符串結果,不包含任何匹配對象!