2013-04-03 25 views
2

我想從字符串中提取方括號中的內容:R:GSUB和捕獲

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中的'替換'參數應該如何(例如\\1\\1_\\2)。 在此先感謝!

回答

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,簡單地搜索模式的字符串,找到它,然後返回所有具有該模式的字符串,這是你的一個字符串。

+0

這工作正常,謝謝!不過,我不明白爲什麼我上面的gsub捕獲不起作用。 – user1981275

+0

現在我明白了爲什麼gsub和grep沒有工作,謝謝澄清! – user1981275

7

另一種選擇:

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

謝謝,這也適用!雖然我寧願堅持使用base-R ... – user1981275

3

gsub替換替換字符串字符串的部分,但在這裏,我們希望提取的字符串,而不是取代他們。

strapplycstrapplycgsubfn package可以做到這一點。用你的模式,但插入您要拍攝的部分加上括號(或省略括號,如果你要拍攝的整個模式包括方括號):

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

strapplyc的膽量寫在TCL因此其相當雖然對於像這樣的小絃線來說速度並不快,但速度並不重要。

strapply還存在strapply它採用第三個參數是應用於每個提取的捕獲的函數,列表或原始對象。例如

> # 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"