2016-11-08 36 views
3

爲什麼這不起作用?試圖做一個負面的前瞻。我試圖從箱子中取出數字,除了在檢疫箱和檢驗箱中。當我用前面的^代碼匹配括號中的所有數字時。當我刪除^它什麼都不匹配。Negative Lookahead RegEx

也可以使用「or operator |」在負面的前瞻?我想有^(?! Quarantine_Bin | Inspection_Bin)

我也試過特別否定[^Quarantine_Bin],它仍然是匹配的。

^(?!Quarantine_Bin)\([0-9]+\) 

數據

Quarantine(2),Other_Bin(2),Quarantine_Bin(2),Quarantine_Bin(2), 
    Quarantine_Bin(5),Inspection_Bin(3),Regular_Bin(5),other(2) 
+0

因此,只有'2'和'5'應該從上面的字符串中提取? https://regex101.com/r/UAlyEG/1? –

+4

但是老實說 - 我會建議像這樣的正則表達式,而不是'split /,/'並將值作爲單獨的測試進行匹配。複雜的正則表達式不適合程序維護。 – Sobrique

+0

@Sobrique每條線可以有不同數量的垃圾桶,所以你會認爲分割是最好的路線? – nzaleski

回答

4

,你應該使用負回顧後爲:

(?<!\b(Quarantine|Inspection)_Bin)\([0-9]+\) 

RegEx Demo

(?<!\b(Quarantine|Inspection)_Bin)是負回顧後發斷言失敗,如果有Quarantine_BinInspection_Bin在你之前r匹配。 \b用於文字邊界。

5

這是一個負回顧後

use warnings; 
use feature 'say'; 

my @strings = (
    "Quarantine_Bin(5),Inspection_Bin(3),Regular_Bin(5),other(2)", 
    "Quarantine(2),Other_Bin(2),Quarantine_Bin(2),Quarantine_Bin(2)," 
); 

for (@strings) { 
    my @m = $_ =~ /(?<!\b(?:Quarantine|Inspection)_Bin)\(\d+\)/g; 
    say "@m"; 
} 

^錨不會做你想要的這裏,用\b指定一個字邊界。

這包括帶數字的括號,返回行(5) (2)(2) (2)

如果你寧願忽略它們,添加捕捉周圍數

/(?<! \b(?: Quarantine|Inspection)_Bin) \((\d+) \)/xg; 

或拉開括號的回顧後內(所以沒有被消耗),並離開了parethesis的關閉一個

/(?<! \b(?: Quarantine|Inspection)_Bin \() \d+/xg; 

這些返回線5 22 2,沒有parens。

修改器/x允許內部空間的可讀性。

2

^(?!Quarantine_Bin)\([0-9]+\)檢查字符串的開頭是否後跟Quarantine_Bin,但後面跟着\([0-9]\)。這永遠不會是真的。

[^Quarantine_Bin]匹配單個字符不能BQaeinrtu_。不是你想要的。


沒有過濾功能,你必須

\b\w+\([0-9]+\) 

你想確保\b後面沒有Quarantine_BinInspection_Bin,所以你可以使用

\b(?!Quarantine_Bin\b)(?!Inspection_Bin\b)\w+\([0-9]+\) 

\b(?!(?:Quarantine|Inspection)_Bin\b)\w+\([0-9]+\) 

內向前\b防止Quarantine_Bin_X被過濾掉。


有用:

(?:(?!STRING).)*就是STRING作爲[^CHAR]*CHAR

1

這是在評論中,所以我會充實它作爲一個實際的答案。

我建議一般避免使用正面/背後的正則表達式,因爲它會變得複雜和凌亂。在你的用例中 - 我可能只是將split行放入數組中,並分別處理每一行。

喜歡的東西:

#!/usr/bin/env perl 
use strict; 
use warnings; 

while (<DATA>) { 
    chomp; 
    #split on comma; 
    #grep out Inspection_Bin and Quarantine_Bin 
    my @fields = grep { not m/(?:Quarantine|Inspection)_Bin/ } split /,/; 
    #iterate each field, and select out two different regex matches, e.g. 
    #word bit and number bit. 
    print m/^(\w+)/, "=>", m/\((\d+)\)/, "\n" for @fields; 
} 


__DATA__ 
Quarantine(2),Other_Bin(2),Quarantine_Bin(2),Quarantine_Bin(2),Quarantine_Bin(5),Inspection_Bin(3),Regular_Bin(5),other(2)