2013-04-03 3 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]" 

Кроме того, в моем приложении я не знаю, сколько таких терминов в квадратных скобках происходит, так что я не знаю как должен выглядеть аргумент «replace» в 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заменяет части строки с заменой строк, но здесь мы хотим экстракте строки, а не заменять их.

ремешок в комплектеstrapplyc в gsubfn package может это сделать. Используйте свой шаблон, но вставить скобки вокруг части, которую Вы хотите захватить (или опустить скобки, если вы хотите, чтобы захватить весь узор, включая квадратные скобки):

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

Внутренность strapplyc написана в Tcl так что его вполне быстро, хотя для небольших струн, таких как здесь, скорость не имеет большого значения.

ремень Существует также 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" 
Смежные вопросы