提取字符串中存在的天数并在r

时间:2019-05-24 11:53:47

标签: r string

我想提取字符串中存在的天数并找到该数字范围(包括范围天数)之间的所有连续数字。 天数出现在between day之后。赞赏是否有人可以建议简单的出路。

strng1 <- 'At 00:00 AM, 07:00 AM, 12:30 PM and 07:00 PM, between day 26 and 31 of the month, only in March, June, September, and December  and  At 00:00 AM, 07:00 AM,12:30 PM and 07:00 PM, between day 1 and 14 of the month, only in January, April, July, and October'
strng2 <- 'At 00:00 AM, 07:00 AM, 12:30 PM and 07:00 PM, between day 26 and 14 of the month'

期望结果出现在列表中,例如:对于strng1 "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "11" "12" "13" "14" "26" "27" "28" "29" "30" "31"strng2 "14" "15" "16" "17" "18" "19" "20" "21" "22" "23" "24" "25" "26"

3 个答案:

答案 0 :(得分:2)

尝试以下方法。
主要功能是seqDigits。它从获取向量列表开始,每个向量在字符串"between day""of the month"之间都有一个数字。然后,它用Reduce/':'产生数字序列,并将它们排序输出。

auxfun <- function(s){
  f <- function(.s){
    m <- gregexpr("\\d+", .s)
    regmatches(.s, m)
  }
  m <- gregexpr("between day \\d+ and \\d+ of the month", s)
  s <- regmatches(s, m)
  sapply(unlist(s), f)
}

seqDigits <- function(X){
  y <- auxfun(X)
  d <- lapply(y, function(x){
    Reduce(':', as.numeric(x[2]), as.numeric(x[1]))
  })
  sort(unname(unlist(d)))
}

seqDigits(strng1)
# [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 26 27 28 29 30 31
seqDigits(strng2)
# [1] 14 15 16 17 18 19 20 21 22 23 24 25 26

答案 1 :(得分:2)

这基本上是通过strsplit来代替Rui的答案:

get_date_range <- function (strng1){
  s <- unlist(strsplit(strng1, 'between day '))[-1]
  .starts <- as.integer(gsub('^(\\d+) and (\\d+).*', '\\1', s, perl = TRUE))
  .ends <- as.integer(gsub('^(\\d+) and (\\d+).*', '\\2', s, perl = TRUE))
  out_list <- Map(f = `:`, .starts, .ends)
  out_vec <- sort(unlist(out_list))
  return (out_vec)
}

# Test
get_date_range(strng1)
# [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 26 27 28 29 30 31
get_date_range(strng2)
# [1] 14 15 16 17 18 19 20 21 22 23 24 25 26

基本上,我们首先使用between day拆分字符串,然后使用^\\d+ and \\d+.*模式提取起始索引和结束索引,并以此创建序列。

答案 2 :(得分:1)

一种非常不整洁的方式:

a = gsub(".*?(day (\\d+) and (\\d+)\\D+).*?(?1)*",'\\2:\\3,',c(strng1,strng2),perl=T)
sapply(parse(text=sub('(.*),$','c(\\1)',a)),function(x)sort(eval(x)))
[[1]]
 [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 26 27 28 29 30 31

[[2]]
 [1] 14 15 16 17 18 19 20 21 22 23 24 25 26