2014-02-14 20 views
1

我有很多日誌與命令在裏面。我與過濾 「useradd」 和所有日誌在其中,但現在我要捨棄一些誤報:python正則表達式不同長度「或」在後退

  • ...的/ etc /默認/ useradd的...
  • .../man8/useradd ...

問題是我想看到行中有誤報和真實命令(參見測試用例)。

我只能使用(一個或多個)python正則表達式,因爲我正在使用日誌分析器程序 - 所以沒有真正的python程序。 這些都是我想表達:

(!/etc/default/|/man8/)useradd # no match 
(?<!/etc/default/|/man8/)useradd # look-behind requires fixed-width pattern 
(?<!fault/|/man8/)useradd # works, but that's strange 

在回答其他問題正則表達式改變了,使得在先行可用於 - 但我不明白這是怎麼可能在這裏。

[編輯:增加了一些測試案例]

## no match 
cat /etc/default/useradd 
less /usr/share/man/ja/man8/useradd.8.gz 
## match: 
useradd evil 
/usr/sbin/useradd 
cat /etc/default/useradd; useradd evil 
cat /etc/default/useradd; /usr/sbin/useradd evil 
cat /etc/default/useradd; cd /usr/lib/; ../sbin/useradd evil 
+0

抱歉,我沒有清楚地說出我想要的,現在應該更清楚 –

+1

如果使用第三方模塊是您的一個選擇,請考慮[regex](https://pypi.python.org/pypi /正則表達式) - 它在很多方面比股票好多了。特別是,它確實支持變量lookbehinds。 – georg

+0

感謝您的信息 - 在這種情況下,這是不可能的,但無論如何我會記住這一點 - 誰知道我什麼時候需要它在Python本身! –

回答

4

您可以使用前向斷言,而不是:

^(?!.*(?:/etc/default|/man8)/useradd(?!.*useradd)).*useradd 

說明:

^    # Start of string 
(?!    # Assert that it's impossible to match... 
.*    # any string, followed by... 
(?:   # this non-capturing group containing... 
    /etc/default # either "/etc/default" 
|    # or 
    /man8   # "/man8" 
)    # End of group, followed by... 
/useradd  # "/useradd" 
(?!.*useradd) # UNLESS another "useradd" follows further up ahead. 
)    # End of lookahead 
.*    # Match anything, then match 
useradd   # "useradd" 

看到它live on regex101.com

+0

@Alex:感謝您創建演示! –

+0

先生,您應該在RegEx上寫一本書。 – thefourtheye

+0

這是原始問題的完美答案 - 但我重新說明了這個問題,它不匹配新的測試用例:( –