从字符串向量中提取数字

use*_*980 78 regex r

我有这样的字符串:

years<-c("20 years old", "1 years old")
Run Code Online (Sandbox Code Playgroud)

我想只grep这个向量中的数字.预期输出是一个向量:

c(20, 1)
Run Code Online (Sandbox Code Playgroud)

我该怎么做呢?

Aru*_*run 71

怎么样

# pattern is by finding a set of numbers in the start and capturing them
as.numeric(gsub("([0-9]+).*$", "\\1", years))
Run Code Online (Sandbox Code Playgroud)

要么

# pattern is to just remove _years_old
as.numeric(gsub(" years old", "", years))
Run Code Online (Sandbox Code Playgroud)

要么

# split by space, get the element in first index
as.numeric(sapply(strsplit(years, " "), "[[", 1))
Run Code Online (Sandbox Code Playgroud)

  • 如果数字不必在字符串的开头,请使用:`gsub(".*?([0-9] +).*","\\ 1",年)` (9认同)
  • 为什么需要`.*`?如果你想在开头使用它们,为什么不使用 `^[[:digit:]]+` 呢? (3认同)
  • `.`是必要的,因为你需要匹配整个字符串.没有它,没有任何东西被删除.另外,请注意,这里可以使用`sub`而不是`gsub`. (2认同)

seb*_*n-c 49

我认为替代是获得解决方案的间接方式.如果您想要检索所有数字,我建议gregexpr:

matches <- regmatches(years, gregexpr("[[:digit:]]+", years))
as.numeric(unlist(matches))
Run Code Online (Sandbox Code Playgroud)

如果你在一个字符串中有多个匹配项,那么这将获得所有匹配项.如果您只对第一场比赛感兴趣,请使用regexpr而不是,gregexpr您可以跳过unlist.


akr*_*run 46

更新extract_numeric不推荐使用以来,我们可以parse_numberreadr包中使用.

library(readr)
parse_number(years)
Run Code Online (Sandbox Code Playgroud)

这是另一种选择 extract_numeric

library(tidyr)
extract_numeric(years)
#[1] 20  1
Run Code Online (Sandbox Code Playgroud)

  • 负数解析错误已修复:https://github.com/tidyverse/readr/issues/308 `readr::parse_number("-12,345") # [1] -12345` (4认同)
  • 对于这个应用程序很好,但请记住 `parse_number` 不处理负数。试试 `parse_number("–27,633")` (3认同)
  • extract_numeric 现已弃用,您将收到使用 readr::parse_number() 的警告 (3认同)
  • @Nettle是的,这是正确的,如果也有多个实例,它就不起作用 (2认同)
  • @NorthLattitude 如果您注意到的话,我确实在“更新”中指定了这一点 (2认同)

And*_*rew 31

这是Arun的第一个解决方案的替代方案,具有更简单的类似Perl的正则表达式:

as.numeric(gsub("[^\\d]+", "", years, perl=TRUE))
Run Code Online (Sandbox Code Playgroud)


989*_*989 19

或者干脆:

as.numeric(gsub("\\D", "", years))
# [1] 20  1
Run Code Online (Sandbox Code Playgroud)

  • `\\D` 是匹配非数字字符的元字符:https://www.w3schools.com/jsref/jsref_regexp_digit_non.asp (2认同)

Joe*_*Joe 17

一个stringr流水线式的解决方案:

library(stringr)
years %>% str_match_all("[0-9]+") %>% unlist %>% as.numeric
Run Code Online (Sandbox Code Playgroud)


Tyl*_*ker 15

你也可以摆脱所有的字母:

as.numeric(gsub("[[:alpha:]]", "", years))
Run Code Online (Sandbox Code Playgroud)

虽然这可能不那么普遍.

  • 奇怪的是,安德鲁的解决方案在我的机器上击败了5倍. (3认同)

Ron*_*hah 11

我们也可以使用str_extractfromstringr

years<-c("20 years old", "1 years old")
as.integer(stringr::str_extract(years, "\\d+"))
#[1] 20  1
Run Code Online (Sandbox Code Playgroud)

如果字符串中有多个数字,并且我们想提取所有数字,我们可以使用str_extract_allwhich str_extractwithout 返回所有 macthes。

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"
Run Code Online (Sandbox Code Playgroud)


sba*_*wal 6

从开始位置的任何字符串中提取数字。

x <- gregexpr("^[0-9]+", years)  # Numbers with any number of digits
x2 <- as.numeric(unlist(regmatches(years, x)))
Run Code Online (Sandbox Code Playgroud)

从位置的任何字符串 INDEPENDENT 中提取数字。

x <- gregexpr("[0-9]+", years)  # Numbers with any number of digits
x2 <- as.numeric(unlist(regmatches(years, x)))
Run Code Online (Sandbox Code Playgroud)


Moo*_*per 6

使用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
Run Code Online (Sandbox Code Playgroud)

由reprex 包(v0.3.0)于 2019-11-06 创建

更多信息:https://github.com/moodymudskipper/unglue/blob/master/README.md


jua*_*tti 5

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]])
Run Code Online (Sandbox Code Playgroud)