2014-10-26 57 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