R:gsub和捕获

时间:2013-04-03 12:46:43

标签: regex string r gsub regex-greedy

我试图从字符串中提取方括号之间的内容:

eq <- "(5) h[m] + nadh[m] + q10[m] --> (4) h[c] + nad[m] + q10h2[m]"

我可以过滤掉它们:

gsub("\\[.+?\\]","" ,eq) ##replaces square brackets and everything inside it
   [1] "(5) h + nadh + q10 --> (4) h + nad + q10h2"

但我如何捕捉括号内的内容?我尝试了以下方法:

gsub("\\[(.+)?\\])", "\\1", eq) 
grep("\\[(.+)?\\]", eq, value=TRUE)

但两个都给我整个字符串:

[1] "(5) h[m] + nadh[m] + q10[m] --> (4) h[c] + nad[m] + q10h2[m]"

另外,在我的应用程序中,我永远不知道方括号中出现了多少这样的术语,所以我不知道gsub中的'replace'参数应该是什么样的(例如\\1\\1_\\2 )。 提前谢谢!

3 个答案:

答案 0 :(得分:8)

试试这个:

eq <- "(5) h[m] + nadh[m] + q10[m] --> (4) h[c] + nad[m] + q10h2[m]"
pattern<-"\\[.+?\\]"
m <- gregexpr(pattern, eq)
regmatches(eq, m)
[[1]]
[1] "[m]" "[m]" "[m]" "[c]" "[m]" "[m]"

由于从未找到过额外的括号,您的第一个模式无效:

gsub("\\[(.+)?\\])", "\\1", eq) # Yours 
gsub("\\[(.+?)\\]", "\\1", eq) # Corrected -- kind of
[1] "(5) hm + nadhm + q10m --> (4) hc + nadm + q10h2m"

你基本上正在做的是用你的第一个括号部分替换你的匹配的每个实例,这不是你想要的。

你的第二个模式,使用grep,只是在字符串中搜索模式,找到它,然后返回所有具有模式的字符串,这是你的一个字符串。

答案 1 :(得分:7)

另一种选择:

library(stringr)
pattern<-"\\[.+?\\]"
str_extract_all(eq,pattern)
[[1]]
[1] "[m]" "[m]" "[m]" "[c]" "[m]" "[m]"

答案 2 :(得分:3)

gsub 用替换字符串替换字符串的部分,但在这里我们希望提取字符串而不是替换它们。

gsubfn package中的

strapplyc strapplyc可以做到这一点。使用您的模式,但在您要捕获的部分周围插入括号(如果您希望捕获包括方括号的整个模式,则省略括号):

> library(gsubfn)
> strapplyc(eq, "\\[(.*?)\\]")[[1]]
[1] "m" "m" "m" "c" "m" "m"

strapplyc的内容是用tcl编写的,所以它的速度非常快,尽管对于像这里的小字符串来说速度并不重要。

strapply 还存在strapply,其中第三个参数是应用于每个提取的捕获的函数,列表或proto对象。 e.g。

> # function
> strapply(eq, "\\[(.*?)\\]", toupper)[[1]]
[1] "M" "M" "M" "C" "M" "M"

> # list
> strapply(eq, "\\[(.*?)\\]", list(c = "crunchy", m = "munchy"))[[1]]
[1] "munchy"  "munchy"  "munchy"  "crunchy" "munchy"  "munchy"