【问题标题】:Combine grep and sub in a single pass?一次通过结合grep和sub?
【发布时间】:2024-01-22 22:39:01
【问题描述】:

我想知道是否有比grepsub 更有效的方法来提取pr

v <- c("a","b","P:18.18% R:66.67%","d")
pr <- grep("^P:([^%]*)% R:([^%]*)%$",v,value=TRUE)
(p <- as.numeric(sub("^P:([^%]*)% R:([^%]*)%$","\\1",pr)))
[1] 18.18
(r <- as.numeric(sub("^P:([^%]*)% R:([^%]*)%$","\\2",pr)))
[1] 66.67

【问题讨论】:

  • 向量v中可以有多个有效字符串吗?
  • @SvenHohenstein:不;那将是一个数据错误(用stopifnot检查)

标签: r regex replace


【解决方案1】:

您可以使用gregexprregmatches 提取两个子字符串:

regmatches(v, gregexpr("(?<=(P|R):).+?(?=%( |))", v, perl = TRUE))


[[1]]
character(0)

[[2]]
character(0)

[[3]]
[1] "18.18" "66.67"

[[4]]
character(0)

您可以使用unlist 创建包含所有结果的单个向量。

unlist(regmatches(v, gregexpr("(?<=(P|R):).+?(?=%( |))", v, perl = TRUE)))

[1] "18.18" "66.67" 

【讨论】:

  • 这仍然会扫描v 两次,对吗?
  • @sds 我想gregexpr 扫描v 一次。
  • ... 然后regmatches 再做一次(但是是的,匹配只发生一次!)
  • @sds regmatches 提取gregexpr返回的位置的子串。