2009-08-20 93 views
4

我對正則表達式相當陌生,需要一些幫助。我需要在Perl中使用正則表達式來過濾一些行。我將把正則表達式傳遞給另一個函數,因此它需要在一行中完成。如何在正則表達式中結合正面和負面條件?

我想選擇僅包含"too long"並沒有開始"SKIPPING"

這裏是我的測試串線:

跳過此債券到期以來太長
TKIPPING該債券自成熟太久
SLAPPING此債券自成熟以來太長
你好這個成熟太久了
這太長了
你好

正則表達式規則應符合在「太長「以下內容:

跳過此債券自到期日太長
打耳光這種債券由於期限過長
你好這個成熟太長
這太長了

它應該跳過:

「你好」,因爲它不包含「過長」
「跳繩,因爲這個成熟債券太長」,因爲它containst「跳繩」

回答

11
/^(?!SKIPPING).*too long/ 
+0

非常酷。謝謝。 我有一種方法去學習正則表達式! – autodidact 2009-08-20 21:02:33

+0

這是如何在Perl中完成負面後視。沒有'<'符號。 – 2009-08-20 21:09:22

+4

其實,這是一個負面的前瞻。否定後視確實有'<'...語法是'(?<!pattern)'。 – chaos 2009-08-20 21:13:04

-2

使用負回顧後:

(?<!^SKIPPING)too long$ 
+0

不起作用。嘗試一下。 – chaos 2009-08-20 20:54:09

+0

我不確定?<!^語法,但它確實應該如下所示:(?<!^ SKIPPING)。*太長 – 2009-08-20 20:57:02

+0

您不能使用可變長度lookbehind。 – Axeman 2009-08-20 21:56:19

10

就個人而言,我會這樣做,作爲兩個單獨的正則表達式,只是爲了使其更清晰。

while (<FILE>) 
{ 
    next if /^SKIPPING/; 
    next if !/too long/; 

    ... do stuff 
} 
+0

-1未答覆。 – 2009-08-20 21:10:16

+9

你是什麼意思「不是答案」?它完全符合他的要求,而不是完全按照他的想法去做。對我來說,這是一個答案。 – 2009-08-20 21:57:44

1

使用向前看;見this explanation of regex lookaround

^(?!SKIPPING).*too long 
+0

不幸的是,該網站對於負面後顧的語法顯然是錯誤的。 – 2009-08-20 21:08:51

+0

@Daniel:不,不是。我想你在這裏很困惑。 – ysth 2009-08-21 00:24:03

+0

@Daniel:網站錯誤?在我認識的每個正則表達式中(支持向後看),負向lookbehind的形式爲'(?<!...)'。也許你正在考慮消極的** lookahead **,'(?!...)'。 – 2009-08-21 00:26:53

3

我懷疑你一個正則表達式之後,也許,但是我更喜歡拆分成更具可讀性的是這樣的:

use strict; 
use warnings; 

for my $line (<DATA>) { 
    next if $line =~ m/^SKIPPING/; 
    next if $line !~ m/too long/; 

    # do something with $line 
    chomp $line; 
    say "Found: ", $line, ':length=', length($line); 
} 

__DATA__ 
SKIPPING this bond since maturity too long 
TKIPPING this bond since maturity too long 
SLAPPING this bond since maturity too long 
Hello this maturity too long 
this is too long 
hello there 
-1
/^(?<!SKIPPING).*too long$/ 

匹配您正在尋找的線條。最後的美元符號會導致它只匹配以「太長」結尾的字符串。

希望這會有所幫助!