2014-10-26 24 views
0

我嘗試提取像44.11.36.00-1(準確地說,nn.nn.nn.nn-n,其中n代表任何數量從0-9)在R.[R正則表達式回顧後先行問題

從文本中我想提取通道的通道,如果他們是「貼「非數字標記:

  • 44.11.36.00-1nsfghstighsl44.11.36.00-1vsdfgh提取正常
  • 44.11.36.00-1fa0044.11.36.00-1000提取不

我已閱讀,str_extract_all沒有與LookbehindLookahead表達式的工作,所以我垂頭喪氣地回來grep,但不能處理它:

> pattern1 <- "(?<![0-9]{1})[0-9]{2}\\.[0-9]{2}\\.[0-9]{2}\\.[0-9]{2}-[0-9]{1}(?![0-9]{1})" 
> grep(pattern1, "dyj44.11.36.00-1aregjspotgji 44113600-1 agdtklj441136001 ", perl=TRUE, value = TRUE) 

[1] "dyj44.11.36.00-1aregjspotgji 44113600-1 agdtklj441136001 " 

這不是我期待的結果。

我認爲:

  • (?<![0-9]{1})手段「匹配表達式,其不是由數preceeded」
  • [0-9]{2}\\.[0-9]{2}\\.[0-9]{2}\\.[0-9]{2}-[0-9]{1}代表我尋求
  • (?![0-9]{1})手段「匹配表達式表達其後面沒有由一個數字「
+0

'grep'不會提取子字符串。你需要'regmatches'。 – Roland 2014-10-26 13:46:37

+0

Roland,請您根據我上面的代碼提供一些快速示例嗎? – 2014-10-26 13:53:12

回答

2

AS @Roland在他的評論中說,你需要使用regmatches inst grep

> s <- "nsfghstighsl44.11.36.00-1vsdfgh" 
> m <- gregexpr("(?<![0-9]{1})[0-9]{2}\\.[0-9]{2}\\.[0-9]{2}\\.[0-9]{2}-[0-9]{1}(?![0-9]{1})", s, perl=TRUE) 
> regmatches(s, m) 
[1] "44.11.36.00-1" 

A的EAD減少了一個,

> x <- c('nsfghstighsl44.11.36.00-1vsdfgh', 'fa0044.11.36.00-1000') 
> m <- gregexpr("(?<!\\d)\\d{2}\\.\\d{2}\\.\\d{2}\\.\\d{2}-\\d(?!\\d)", x, perl=TRUE) 
> regmatches(x, m) 
[1] "44.11.36.00-1" 
+0

謝謝Avinash Raj爲這個答案!這是訣竅:) – 2014-10-26 13:57:35

+0

我注意到regexpr只匹配patter-matching子字符串的第一次出現。有什麼方法可以改變它嗎? – 2014-10-26 14:11:42

+0

使用'gregexpr' ..' – 2014-10-26 14:13:03

3

你實際上並不需要先行或使用這種方法回顧後。只是加上括號你想要的部分提取:

library(gsubfn) 
x <- c("nsfghstighsl44.11.36.00-1vsdfgh", "fa0044.11.36.00-1000") # test data 

pat <- "(^|\\D)(\\d{2}[.]\\d{2}[.]\\d{2}[.]\\d{2}-\\d)(\\D|$)" 
strapply(x, pat, ~ ..2, simplify = c) 

## "44.11.36.00-1" 

注意~ ..2是短期的功能function(...) ..2這意味着抓住了比賽的正則表達式的第二括號內的部分。我們也可以寫function(x, y, z) yx + y + z ~ y

注:這個問題似乎是說,一個非數字必須直接來之前並後串,但根據已經因爲消失了,似乎什麼真正想要的是該字符串是無論是在年初的意見或者在一個非數字之後,並且必須在最後或非數字之後。答案已經過修改。

+0

我已經修改了答案,要求在匹配之前非數字或字符串的開頭直接出現,並且非數字或字符串結尾緊接在匹配之後。 – 2014-10-26 15:30:02