0

我尝试从 R 中的文本中提取像44.11.36.00-1(准确地说,nn.nn.nn.nn-n代表n0-9 之间的任何数字)这样的段落。

如果段落“粘”在非数字标记上,我想提取它们:

  • 44.11.36.00-1从中提取nsfghstighsl44.11.36.00-1vsdfgh是可以的
  • 44.11.36.00-1提取自fa0044.11.36.00-1000is NOT

我读过那str_extract_all不适用于LookbehindandLookahead表达式,所以我很遗憾地回到了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})意思是“匹配前面没有数字的表达式”
  • [0-9]{2}\\.[0-9]{2}\\.[0-9]{2}\\.[0-9]{2}-[0-9]{1}代表我寻求的表达
  • (?![0-9]{1}) 意思是“匹配不带数字的表达式”
4

2 回答 2

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

注意:问题似乎是说非数字必须直接出现在字符串之前和之后,但根据已经消失的评论,似乎真正想要的是字符串要么在开头,要么就在非数字之后数字,并且必须在末尾或后跟非数字。答案已经如此修改。

于 2014-10-26T13:58:05.027 回答
2

正如@Roland 在他的评论中所说,你需要使用regmatches而不是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"

一个缩小的,

> 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"
于 2014-10-26T13:55:37.957 回答