2011-12-23 27 views
28

Tôi có một chuỗi ký tự và những gì để trích xuất thông tin bên trong nhiều dấu ngoặc đơn. Hiện tại tôi có thể trích xuất thông tin từ dấu ngoặc đơn cuối cùng bằng mã bên dưới. Làm thế nào tôi sẽ làm điều đó để nó trích xuất nhiều dấu ngoặc đơn và trả về dưới dạng vectơ?Trích xuất thông tin bên trong tất cả dấu ngoặc đơn trong R

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

sản lượng hiện tại là:

[1] "Laugh" 

đầu ra mong muốn là:

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

Trả lời

30

Dưới đây là một ví dụ:

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

Tôi nghĩ rằng điều này sẽ làm việc tốt:

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

nhưng kết quả bao gồm dấu ngoặc đơn ... tại sao?

này hoạt động:

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

Cảm ơn @MartinMorgan cho nhận xét.

+1

LƯU Ý: Thao tác này sẽ hoạt động cho vectơ nhưng sẽ không hoạt động cho văn bản trong cột của khung dữ liệu. – AudileF

13

Sử dụng gói stringr, chúng tôi có thể giảm bớt điều này một chút.

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 sử dụng regmatch nhưng tôi hiện đang sử dụng 2.13 để không có quyền truy cập vào chức năng đó vào lúc này. Điều này thêm phụ thuộc vào stringr nhưng tôi nghĩ rằng nó là một chút dễ dàng hơn để làm việc với và mã là một chút rõ ràng hơn (cũng ... rõ ràng như bằng cách sử dụng các biểu thức thông thường có thể ...)

Edit: chúng tôi cũng có thể hãy thử một cái gì đó như thế này -

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

Điều này hoạt động bằng cách xác định biểu hiện dưới được đánh dấu bên trong cụm từ thông dụng. Nó trích xuất mọi thứ phù hợp với regex và sau đó gsub chỉ chiết xuất phần bên trong biểu thức con.

3

Sử dụng rex có thể làm cho loại công việc này đơn giản hơn một chút.

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

matches[[1]]$text 
#>[1] "wonder" "groan" "Laugh" 
Các vấn đề liên quan