从字符串中提取数字然后将其作为日期

Extract numbers from a string then make it as a date

您好,我正在尝试从以下字符串中提取年、月和日期

"2020y 3m 1d 16h"

并希望得到如下输出:

“2020-03-01”(或“2020-3-1”但日期类型)

我试过向上搜索 Google 但只能得到 [使用特定模式提取 - 大多数都有标点符号模式],[提取所有数字 - 很难删除 16 等].

有人可以帮我解决这个问题吗?

在此先感谢您!

我们可以先从输入中删除“__h”字符串,然后使用lubridate包中的ymd()函数将其转换为日期。

正则表达式:

  • \s任意白色space(匹配“16h”之前的space)
  • \d{1,2} 任何出现 1 到 2 次的数字(因为小时的范围应该是 00 到 23 或 24,最多只有两位数)
library(lubridate)

ymd(gsub("\s\d{1,2}h", "", "2020y 3m 1d 16h"))
[1] "2020-03-01"

class(ymd(gsub("\s\d{1,2}h", "", "2020y 3m 1d 16h")))
[1] "Date"

将 y、m、d 字符转换为短划线,然后使用 as.POSIXct 转换为日期时间 class。空格可能不会出现在 10 或以上的月份或日期。

as.POSIXct( gsub("[y|m|d]( ){0,1}", "-", test),format="%Y-%m-%d-%Hh")
#[1] "2020-03-01 16:00:00 CST"

这样的输入也能成功:

test <- "2020y12m 1d 16h"

...而 benson23 的回答失败了。如果您打算丢弃小时信息,格式字符串可以是:

..., format="%Y-%m-%d"

as.POSIXct( gsub("[y|m|d]( ){0,1}", "-", test),format="%Y-%m-%d")

您通常应该提供更多可能的输入来支持代码测试。

您可以在 strsplit 将字符串添加到一个或多个 non-digits \D+.

之后使用 ISOdate
r1 <- simplify2array(strsplit(x, '\D+')) |> t() |> as.data.frame() |> unname() |>
  do.call(what='ISOdate') |> as.Date()
r1
# [1] "2020-03-01" "2020-12-01" "2020-12-12"
    
class(r1)
[1] "Date"

如果您省略 as.Date,您甚至会随着时间的推移得到 "POSIXt" class。

r2 <- simplify2array(strsplit(x, '\D+')) |> t() |> as.data.frame() |> unname() |>
  do.call(what='ISOdate')
r2
# [1] "2020-03-01 16:00:00 GMT" "2020-12-01 16:00:00 GMT" "2020-12-12 01:00:00 GMT"
    
class(r2)
# [1] "POSIXct" "POSIXt" 

数据:

x <- c("2020y 3m 1d 16h", "2020y 12m 1d 16h", "2020y 12m 12d 1h")