【问题标题】:Using R for regex IP address in text在文本中使用 R 作为正则表达式 IP 地址
【发布时间】:2016-01-07 22:58:06
【问题描述】:

我正在尝试解析每行中都有文本的数据框,并且在该文本中存在我想要隔离的 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。谢谢。

【问题讨论】:

标签: regex r gsub


【解决方案1】:

我认为这应该可行:

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),否则返回空结果。


更新:

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

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

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

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" 

如果您确实想将每个结果分解为自己的字符串,则表达式会更简单一些(与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
)

【讨论】:

  • 谢谢 nrussell。这很好用。还有一个问题,如果我在同一个单元格中有多个 IP,我将如何修改它以捕获 1 个或多个 IP。例如:z
  • 应该将多个ip拆分成自己的字符串,还是保持组合(例如用空格分隔)?
  • 就我的项目而言,我将它们组合成一个单元格/元素(由空格分隔),稍后我将它们分开。我希望他们保留关联的索引。谢谢。
猜你喜欢
  • 2011-06-20
  • 2017-03-15
  • 2015-11-22
  • 2011-08-27
  • 2013-02-21
  • 1970-01-01
相关资源
最近更新 更多