在文本中使用 R 作为正则表达式 IP 地址

Using R for regex IP address in text

我正在尝试解析一个数据框,该数据框的每一行都有文本,并且在该文本中有我想要隔离的 IP 地址。但是,我仍在选择整数、整数和句点。下面是我正在使用的示例。

    z <- data.frame( x =  c('112.68.196.98   5.32', '192.41.196.888', '..','5.32  88'))
    gsub("^\.+|\.[^.]*$", "", z$x, perl=TRUE)

我希望清理此数据框,因此输出将是:

    z <- data.frame( x =  c('112.68.196.98', '192.41.196.888','',''))

我似乎想不出要放入 gsub 中的正确正则表达式。谢谢。

我认为这应该有效:

re <- regexpr(
  "(?(?=.*?(\d+\.\d+\.\d+\.\d+).*?)(\1|))", 
  z$x, perl = TRUE)

regmatches(z$x, re)
#[1] "112.68.196.98"  "192.41.196.888" ""               ""

这使用有条件的正则表达式,在 .*?(\d+\.\d+\.\d+\.\d+).*? 上的正匹配的情况下保留捕获组 (\1),否则 return 为空结果。


更新:

关于您的评论,我认为以下更改将使您能够在一个字符串中捕获多个 IP 地址。首先,从 regexpr 切换到 gregexpr 以允许多个结果:

re2 <- gregexpr(
  "(?(?=.*?(\d+\.\d+\.\d+\.\d+).*?)(\1|))", 
  z2$x, perl = TRUE
)

由于在 gregexpr 输入上调用 regmatches 将 return 一个列表,因此需要一些额外的处理:

res2 <- sapply(regmatches(z2$x, re2), function(x) {
  gsub(
    "^\s+|\s+$", "", 
    gsub("\s+", " ", paste0(x, collapse = " "))
  )
}

这应该适合,例如,与您的 data.frame 重新组合为一个新列:

res2
#[1] "112.68.196.98 192.41.196.888" "192.41.196.888"               
#     ""                             "112.68.196.98" 

如果您 did 想将每个结果分解成自己的字符串,则表达式稍微简单一些(与 sapply(...) 相比):

lapply(regmatches(z2$x, re2), function(x) {
  Filter(function(y) y != "", x)
})
#[[1]]
#[1] "112.68.196.98"  "192.41.196.888"

#[[2]]
#[1] "192.41.196.888"

#[[3]]
#character(0)

#[[4]]
#[1] "112.68.196.98"

数据:

z2 <- data.frame(
  x = c('112.68.196.98 5.32 192.41.196.888', 
        '192.41.196.888', 
        '..', '5.32 88 112.68.196.98'),
  stringsAsFactors = FALSE
)