在R中的所有括号内提取信息

时间:2011-12-23 07:10:26

标签: regex r

我有一个字符串以及在多个括号内提取信息的内容。目前,我可以使用下面的代码从最后一个括号中提取信息。我该怎么做才能提取多个括号并作为向量返回?

j <- "What kind of cheese isn't your cheese? (wonder) Nacho cheese! (groan) (Laugh)"                                                          
sub("\\).*", "", sub(".*\\(", "", j)) 

当前输出为:

[1] "Laugh"

所需的输出是:

[1] "wonder" "groan"  "Laugh" 

4 个答案:

答案 0 :(得分:49)

以下是一个例子:

> gsub("[\\(\\)]", "", regmatches(j, gregexpr("\\(.*?\\)", j))[[1]])
[1] "wonder" "groan"  "Laugh" 

我认为这应该运作良好:

> regmatches(j, gregexpr("(?=\\().*?(?<=\\))", j, perl=T))[[1]]
[1] "(wonder)" "(groan)"  "(Laugh)" 

但结果包括括号......为什么?

这有效:

regmatches(j, gregexpr("(?<=\\().*?(?=\\))", j, perl=T))[[1]]

感谢@MartinMorgan的评论。

答案 1 :(得分:18)

使用stringr包我们可以减少一点。

library(stringr)
# Get the parenthesis and what is inside
k <- str_extract_all(j, "\\([^()]+\\)")[[1]]
# Remove parenthesis
k <- substring(k, 2, nchar(k)-1)

@kohske使用regmatches但我目前正在使用2.13,所以目前无法访问该功能。这增加了对stringr的依赖,但我觉得它更容易使用,代码更清晰一点(好吧......就像使用正则表达式一样明确......)

编辑:我们也可以尝试这样的事情 -

re <- "\\(([^()]+)\\)"
gsub(re, "\\1", str_extract_all(j, re)[[1]])

这个通过在正则表达式中定义标记的子表达式来工作。它提取与正则表达式匹配的所有内容,然后gsub仅提取子表达式中的部分。

答案 2 :(得分:5)

使用rex可能会使这类任务变得更简单。

matches <- re_matches(j,
  rex(
    "(",
    capture(name = "text", except_any_of(")")),
    ")"),
  global = TRUE)

matches[[1]]$text
#>[1] "wonder" "groan"  "Laugh"

答案 3 :(得分:4)

我认为基本上有三种简单的方法可以提取R中的多个捕获组(不使用替代); str_match_allstr_extract_allregmatches/gregexpr组合。

我喜欢@kohske的正则表达式,它的后面是一个开放的括号?<=\\(,后面是一个封闭的括号?=\\),并在中间(懒洋洋地).+?中捕获所有内容其他词(?<=\\().+?(?=\\))

使用相同的正则表达式:

str_match_all将答案作为矩阵返回。

str_match_all(j, "(?<=\\().+?(?=\\))")

     [,1]    
[1,] "wonder"
[2,] "groan" 
[3,] "Laugh" 

# Subset the matrix like this....

str_match_all(j, "(?<=\\().+?(?=\\))")[[1]][,1]
[1] "wonder" "groan"  "Laugh" 

str_extract_all将答案作为列表返回。

str_extract_all(j,  "(?<=\\().+?(?=\\))")
[[1]]
[1] "wonder" "groan"  "Laugh" 

#Subset the list...
str_extract_all(j,  "(?<=\\().+?(?=\\))")[[1]]
[1] "wonder" "groan"  "Laugh" 

regmatches/gregexpr还以列表的形式返回答案。由于这是基本的R选项,因此有些人喜欢它。请注意推荐的perl = TRUE

regmatches(j, gregexpr( "(?<=\\().+?(?=\\))", j, perl = T))
[[1]]
[1] "wonder" "groan"  "Laugh" 

#Subset the list...
regmatches(j, gregexpr( "(?<=\\().+?(?=\\))", j, perl = T))[[1]]
[1] "wonder" "groan"  "Laugh" 

希望,如果我误解了最受欢迎的选项,那么SO社区将纠正/编辑此答案。