2013-01-12 19 views
0

我想匹配「錯誤」的任何變體(讓我們假設整個棋盤上不區分大小寫),其中可能有也可能不跟隨字符,並且可能有或沒有「s」。如果一個字符跟隨另一個字符(可選),我不想匹配

例如,如果它具有以下,返回匹配的行:

text error: more text 
text error more text 
text errors more text 
text errors(more text 
text errors: more text 
text errors:more text 

但如果有一個等號後不久,我不希望它返回的行。例如:

text errors= more text 

基本上,在「error」或「errors」後面有一個「=」符號時,它總是「錯誤」。

我無法想出比這更:

(?i)errors?[^\=] 

不區分大小寫,字符E,R,R,O,R,也許一個s,而不是接着是「= 「是我閱讀的方式。

1 sample text, more text, errors=123456 more text more text 
2 drops=0 link status good errors=0 adapter 
3 Error: process failed to start 
4 process [ERROR] failed 
5 this line might have both ERROR and error=5555 and more text 
6 there might be a line that has error=0x02343329 ERROR and more text 

我想線3,4,5,和6被返回,而不是1或2。

不具有成功。我在這裏先向您的幫助表示感謝。

+0

'errors?'使整個字符串'errors'可選。這可能是爲什麼3-6沒有返回。你會想'錯誤(s?)'而不是。 – dzieciou

+1

也等號需要轉義,所以你應該有'='而不是'\ ='。 – dzieciou

+2

@dzieciou「錯誤?使整個字符串錯誤可選。」< - 錯誤,它只能使'''可選 – fge

回答

-1

零寬度預測是一個很好的答案。嘗試:?

(?i)(?!errors?=)error 

其中「(?!errors?=)」是指「不期而遇提前檢查不匹配‘錯誤=’

更新: 這是通過在原有的正則表達式(?i)errors?[^\=]解釋的問題問題: 的併發症是如何以及何時「貪婪」(人perlre)不是因爲貪婪,因爲它可能是,引用:

By default, a quantified subpattern is "greedy", that is, it will match as many times as possible (given a particular starting location) while still allowing the rest of the pattern to match.

注意句子的第二部分的原始表達式(?i)errors?[^\=]將匹配「errors =」(或「errors」),因爲「s?」允許匹配0次以允許「[^ =]」匹配「s」。 這就是爲什麼它匹配6個編號的行。

當這樣的匹配(*,+,?等)被拒絕時,正則表達式引擎內發生的事情稱爲「回溯」,匹配備份並嘗試不同的路徑,以查看是否更好地匹配整個整體正則表達式是可能的。獨立的子表達式(?>),lookarounds(?=)(?!)及其消極形式可以防止或限制回溯,就像使用交替一樣,似乎每個人都有不同的偏好,因爲我認爲他們大多數都出現在某處。儘管目前爲止沒有人使用「所有格」爲您的原始正則表達式提供最小的無回溯變化?+形式:

errors?+[^\=] 
+0

這一個似乎工作沒有失敗。我看到了很多我想看到的東西。謝謝。 – harperville

+0

我不確定這是否會允許包含錯誤和錯誤=的行,然後將其返回。我對錯誤很感興趣,只要它沒有跟隨=,但如果錯誤和錯誤=在同一行,我仍然希望它返回。 – harperville

+0

@haperville,您是否在http://regex101.com/r/xV2aG6上嘗試了答案? – dzieciou

0

嘗試使用向前斷言:

(?i)errors?(?!\=) 
+0

如果全部是關於找到匹配的行而不是匹配的子字符串,那麼這將如何改變結果? – dzieciou

+0

將文本拆分\ n,然後將每行與正則表達式匹配。 –

+0

我的意思是,'(?i)錯誤?(?!\ =)'和'(?i)錯誤?[^ \ =]'之間沒有區別。 – dzieciou

0

怎麼樣的邏輯OR?

(?i)error[^s=]|errors[^=] 
+0

表達式的第一部分將與'error ='匹配,這不是OP想要的。 – dzieciou

+0

@dzieciou我想你可能誤解了他寫的東西。例如,查看包含子字符串'error ='的測試用例#5和#6。請注意,OP說#5和#6是他想要返回的行。也許你正在考慮'錯誤='(即複數)? – David

+0

這個問題似乎令人困惑,這就是爲什麼我們以不同的方式解釋它。我明白第五個返回,因爲它包含字符串'錯誤'。另外OP寫道:「不區分大小寫,字符e,r,r,o,r,也許是s,而不是後面跟着」=「是我閱讀的方式。」 – dzieciou

0

嘗試:

(?i)\berror(?!s?=) 

字錨,隨後error,只要它不跟一個可選的s然後等號。

(?!...)是負先行,也是在這個意義上的錨定(如^$),它不消耗文本(它是一個零寬度斷言)。

1

這麼多的答案,如此接近他們所有人。你想要的是:/error(?!s=)/im

你不需要使用內聯組,而是使用/ i標誌。

我可能錯過了你的問題,我不確定。但是,如果您也想禁止error=blah,則只需使用/error(?!s?=)/im

演示+解釋:http://regex101.com/r/oE1eQ9

+0

+1用於在線演示結果。 – dzieciou

0

哦,親愛的。很多人認爲他們知道正則表達式!

在自己的正則表達式(?i)errors?[^\=](其中,正如有人所說,=不需要逃避,但它並沒有壞處)[^\=]並不頗有意味「後面沒有一個等號」,它意味着「之後一個不是等號的字符「。除非error位於字符串末尾,否則兩者相同,因此'error' =~ (?i)errors?[^\=]返回false。

「後面沒有一個等號」需要負先行,所以乍一看它看起來像你想(?i)errors?(?!=),但如果正則表達式引擎找到errors=它會走回頭路,儘量不選購s匹配,看是否它可以得到整個模式匹配的方式,然後將成功,因爲errorserror後面沒有等號。

要解決此問題,您需要無回溯構造(?>...),一旦找到匹配項就不允許回溯。正則表達式(?i)(?>errors?)(?!=)做你所需要的。

最後,爲了允許拒絕等於「errorerrors之後不久」,在它之前需要一些可選的空白區域,給出(?i)(?>errors?)(?!\s*=)

此程序演示

use strict; 
use warnings; 

while (<DATA>) { 
    chomp; 
    printf "%-70s %s\n", $_, /(?i)(?>errors?)(?!\s*=)/ ? 'YES' : 'NO'; 
} 

__DATA__ 
text error: more text 
text error more text 
text errors more text 
text errors(more text 
text errors: more text 
text errors:more text 
text errors= more tex 
text errors = more tex 
text error= more tex 
text error = more tex 
1 sample text, more text, errors=123456 more text more text 
2 drops=0 link status good errors=0 adapter 
3 Error: process failed to start 
4 process [ERROR] failed 
5 this line might have both ERROR and error=5555 and more text 
6 there might be a line that has error=0x02343329 ERROR and more text 

輸出

text error: more text             YES 
text error more text             YES 
text errors more text             YES 
text errors(more text             YES 
text errors: more text             YES 
text errors:more text             YES 
text errors= more tex             NO 
text errors = more tex             NO 
text error= more tex             NO 
text error = more tex             NO 
1 sample text, more text, errors=123456 more text more text   NO 
2 drops=0 link status good errors=0 adapter       NO 
3 Error: process failed to start          YES 
4 process [ERROR] failed            YES 
5 this line might have both ERROR and error=5555 and more text   YES 
6 there might be a line that has error=0x02343329 ERROR and more text YES 
1

所以,你想匹配 「錯誤」,只要它不跟 「=」 或 「S =」。這是很簡單的:

/error(?!=|s=)/ 

你甚至可以把它寫成

/error(?!s?=)/ 

如果你真的想如果可能的話(爲了設置${^MATCH}什麼的),則可以使用

匹配的「錯誤」
/error(?![s=])|errors(?!=)/ 

您遇到問題,因爲/ [^=] /匹配項「s」。

相關問題