我有这样的字符串:
years<-c("20 years old", "1 years old")
我只想从这个向量grep数字。预期输出是向量:
c(20, 1)
我该怎么做呢?
Answers:
怎么样
# pattern is by finding a set of numbers in the start and capturing them
as.numeric(gsub("([0-9]+).*$", "\\1", years))
要么
# pattern is to just remove _years_old
as.numeric(gsub(" years old", "", years))
要么
# split by space, get the element in first index
as.numeric(sapply(strsplit(years, " "), "[[", 1))
.*
是必需的,因为您需要匹配整个字符串。没有那个,什么也不会清除。另外,请注意,sub
此处可以使用代替gsub
。
gsub(".*?([0-9]+).*", "\\1", years)
gsub(".*?([0-9]+).*?", "\\1", "Jun. 27–30")
结果:[1]“ 2730” gsub(".*?([0-9]+)\\-.*?", "\\1", "Jun. 27–30")
结果:[1]“ 6月27日–30“
我认为替代是解决方案的间接方式。如果要检索所有数字,我建议gregexpr
:
matches <- regmatches(years, gregexpr("[[:digit:]]+", years))
as.numeric(unlist(matches))
如果字符串中有多个匹配项,则将所有这些匹配项。如果您只对第一个比赛感兴趣,请使用regexpr
代替,gregexpr
然后跳过unlist
。
gregexpr
,regexpr
或两者兼而有之?
gregexpr
。regexpr
直到现在我还没有尝试过。巨大的差异。regexpr
在1e6集上,使用将其置于Andrew和Arun的解决方案之间(第二快)。也许也很有趣,sub
在Andrew的解决方案中使用并不能提高速度。
更新
由于extract_numeric
不建议使用,我们可以使用parse_number
from readr
包。
library(readr)
parse_number(years)
这是另一种选择 extract_numeric
library(tidyr)
extract_numeric(years)
#[1] 20 1
parse_number
不要使用负数。试试 parse_number("–27,633")
readr::parse_number("-12,345") # [1] -12345
我们也可以使用str_extract
从stringr
years<-c("20 years old", "1 years old")
as.integer(stringr::str_extract(years, "\\d+"))
#[1] 20 1
如果字符串中有多个数字,并且我们想提取所有数字,则可以使用str_extract_all
与str_extract
返回所有宏不同 的数字。
years<-c("20 years old and 21", "1 years old")
stringr::str_extract(years, "\\d+")
#[1] "20" "1"
stringr::str_extract_all(years, "\\d+")
#[[1]]
#[1] "20" "21"
#[[2]]
#[1] "1"
来自Gabor Grothendieck的 帖子在r-help邮件列表中
years<-c("20 years old", "1 years old")
library(gsubfn)
pat <- "[-+.e0-9]*\\d"
sapply(years, function(x) strapply(x, pat, as.numeric)[[1]])
使用unglue包,我们可以做:
# install.packages("unglue")
library(unglue)
years<-c("20 years old", "1 years old")
unglue_vec(years, "{x} years old", convert = TRUE)
#> [1] 20 1
由reprex软件包(v0.3.0)创建于2019-11-06
更多信息:https : //github.com/moodymudskipper/unglue/blob/master/README.md
.*
必要?如果您想一开始就使用它们,为什么不使用^[[:digit:]]+
?