正则表达式 – 处理由天,小时,分钟和秒定义的持续时间,例如R中的“1d 3h 2m 28s”

我有一个带有字符向量的数据框,格式为天,小时,分钟和秒,表示为“1d 3h 2m 28s”:
> head(status[5])
    Duration 
1 0d 20h 46m 31s 
2  2d  0h 13m 54s
3  2d  0h 13m 53s
4  0d  9h 53m 38s
5  5d 12h 17m 37s
6  0d 10h 21m 19s

我可以使用正则表达式为组件解析它,但无法想出将持续时间转换为秒的好方法.我可以将向量gsub到一个表达式,该表达式将导致秒数,但是在结果上使用eval时会遇到一个路障.

我可以做类似于推荐的here,但希望遵循正则表达式路线 – 即使它不是最有效的.我只处理解析各种小型HTML表.

status$duration <- gsub("(\\d+)d\\s+(\\d+)h\\s+(\\d+)m\\s+(\\d+)s.*","\\1*86400+\\2*3600+\\3*60+\\4",as.character(status[,5]),perl=TRUE)

上面创建了一个可以计算的表达式,但是当涉及到解析(text = status $duration)和后续的eval时,我遗漏了一些东西.

在perl中,我习惯于在正则表达式中使用“捕获的变量”并立即使用它们而不是仅在替换字符串中使用它们. R中是否有类似的可能性?

谢谢,由于头脑模糊,我可能会遗漏一些非常简单的东西.

下面的第一个和最后一个解决方案似乎是最简单的,但具有复杂正则表达式的解决方案更接近于perl中可能完成的工作.

在列出解决方案本身之前,请注意,在它们中我们假设输入是tt,转换向量mult是4向量,其组件是一天,一小时,一分钟和一秒中的秒数.我们可以在注释中设置mult或如下所示计算它:

tt <- c("0d 20h 46m 31s","2d 0h 13m 54s","2d 0h 13m 53s","0d 9h 53m 38s","5d 12h 17m 37s","0d 10h 21m 19s")
# mult <- c(86400,3600,60,1)
mult <- rev(cumprod(rev(c(24,1))))

以下是4种方法

1)strapply提取数字我们可以在gsubfn包中使用strapply来避免复杂的正则表达式. strapply用于提取所有数字,并将它们排列在一个矩阵中,并乘以多个字符串输出结果:

library(gsubfn)
mat <- strapply(tt,"\\d+",as.numeric,simplify = TRUE)
secs <- c(mult %*% mat)

这两行可以组合成一个单独的声明,但我们将保留它,如果您希望单独检查垫.

2)复杂的正则表达式的另一种可能性,也使用strapply是以下单个语句.捕获的字符串在遇到它们时被放入自由变量中,因此第一次捕获进入白天,第二次进入小时等等.这可能更接近你在perl中所做的事情:

secs <- strapply(tt,"(\\d+)d (\\d+)h (\\d+)m (\\d+)s",~ 86400 * as.numeric(day) + 3600 * as.numeric(hour) + 
    60 * as.numeric(minute) + as.numeric(second),simplify = TRUE)

3)复杂的正则表达式,但矢量化甚至更短:

secs <- strapply(tt,~ as.numeric(list(...)) %*% mult,simplify = TRUE)

4)strsplit,这是另一个单一的陈述答案.这个不使用strapply但是利用了这样一个事实,即字符串末尾的匹配分隔符只是被移除而没有下面的空字符串输出.有关详细信息,请参阅?strsplit.

secs <- sapply(strsplit(tt,"[dhms]"),function(x) as.numeric(x) %*% mult)

上述任何结果都是:

> secs
[1]  74791 173634 173633  35618 476257  37279

相关文章

正则替换html代码中img标签的src值在开发富文本信息在移动端...
正则表达式
AWK是一种处理文本文件的语言,是一个强大的文件分析工具。它...
正则表达式是特殊的字符序列,利用事先定义好的特定字符以及...
Python界一名小学生,热心分享编程学习。
收集整理每周优质开发者内容,包括、、等方面。每周五定期发...