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