Извлечь информацию внутри всех круглых скобок в R

У меня есть строка символов, а информация о том, что извлекать, заключена в круглые скобки. В настоящее время я могу извлечь информацию из последней скобки с помощью приведенного ниже кода. Как мне сделать так, чтобы он извлекал несколько скобок и возвращался как вектор?

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

Текущий вывод:

[1] "Laugh"

Желаемый результат:

[1] "wonder" "groan"  "Laugh" 
44
задан Artem Klevtsov 8 December 2015 в 05:40
поделиться

2 ответа

Я думаю, что есть три простых способа извлечения нескольких групп захвата в R (без использования замещения); str_match_all, str_extract_all и regmatches/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" 

Надеюсь, Сообщество исправит / отредактирует этот ответ, если я неправильно определил наиболее популярные варианты.

7
ответ дан 26 November 2019 в 22:03
поделиться

Используя пакет 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 использует соответствия, но в настоящее время я использую 2.13, поэтому в данный момент у меня нет доступа к этой функции. Это добавляет зависимость от stringr, но я думаю, что с ней немного легче работать, а код немного понятнее (ну ... так же ясно, как можно использовать регулярные выражения ...)

Правка может также попробовать что-то вроде этого -

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

Этот работает, определяя отмеченное подвыражение внутри регулярного выражения. Он извлекает все, что соответствует регулярному выражению, а затем gsub извлекает только часть внутри подвыражения.

21
ответ дан 26 November 2019 в 22:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: