2017-01-23 50 views
2

我正嘗試使用多個lookahead來模擬R運算符Perl類型爲grep的正則表達式。但是,我不明白我看到的輸出。這是一個示例碼塊在R正則表達式中瞭解lookahead

a <- c("abcxyz", "abcdef", "defxyz", "abcdefxyz", "xyzdefabc") 
grep("(?<=abc)(?=xyz)", a, ignore.case=TRUE, perl=TRUE) # returns 1 
grep("(?=abc)(?=xyz)", a, ignore.case=TRUE, perl=TRUE) # returns integer(0) 

第二行表明,該串中的位置爲abc和XYZ,和匹配「abcxyz」之間。它爲什麼不匹配'abcdefxyz'?

在第三行,我試圖輸出1,4和5,但它沒有找到。這是爲什麼發生?

我正在使用下面的替代解決方案,但是我想在處理多個lookahead時使用lookahead來處理排序。

grep("abc.*xyz|xyz.*abc", a, ignore.case=TRUE, perl=TRUE) # returns 1 4 5 as expected 
+0

在第二選項中,使用兩個'='代替'<='?。也許你需要'grep(「(?<= abc)。*(?= xyz)」,a,ignore.case = TRUE,perl = TRUE)' – akrun

+0

@akrun我試圖避免使用回頭看,它強制執行一個我不想要的命令。我編輯了示例代碼以使其更清晰。我的期望是從這個例子:http://www.rexegg.com/regex-lookarounds.html – Naumz

回答

2

的正則表達式(?<=abc)(?=xyz)只匹配的位置(發生在串),該abcxyz之間。它會在abcxyz中找到匹配項,但在abcdefxyz中找不到匹配項,因爲xyz不會立即跟隨abc

,因爲它在隨後與應等於abcxyz在同一時間,這是一個不可能完成的3個字母序列的字符串位置匹配的(?=abc)(?=xyz)模式將不會匹配任何東西。

你所尋找的是

^(?=.*abc)(?=.*xyz) 

或者,支持多線路輸入添加DOTALL修飾符(?s)(這樣.可以匹配換行符,太):

(?s)^(?=.*abc)(?=.*xyz) 

這些都會以任何順序匹配具有abcxyz的字符串。

R demo參見:

a <- c("abcxyz", "abcdef", "defxyz", "abcdefxyz", "xyzdefabc") 
grep("^(?=.*abc)(?=.*xyz)", a, ignore.case=TRUE, perl=TRUE) 
## => [1] 1 4 5 
+0

謝謝你的答案!我想我現在明白我的混亂之源。使用'「(?= abc)(?= xyz)」',第一部分將位置設置爲發生'abc'之前,因此第二部分不能與該位置處的'xyz'匹配。這是正確的嗎? – Naumz

+1

'(?= abc)'檢查一個位置befire'abc',一旦找到它,正則表達式引擎就試圖在這個地方找到'xyz'(因爲'(?= ...)'是零寬度斷言,當找到前瞻模式匹配時它不移動正則表達式索引)。 'abc'不能是'xyz',因此找不到匹配。 –