Estrai il testo tra parentesi in R




str_detect r (2)

Due domande correlate. Ho dei vettori di dati di testo come

"a(b)jk(p)"  "ipq"  "e(ijkl)"

e voglio separarlo facilmente in un vettore che contiene il testo FUORI dalle parentesi:

"ajk"  "ipq"  "e"

e un vettore contenente il testo ALL'INTERNO delle parentesi:

"bp"   ""  "ijkl"

C'è un modo semplice per farlo? Una difficoltà aggiunta è che questi possono diventare piuttosto grandi e avere un numero (illimitato) di parentesi. Quindi, non posso semplicemente afferrare il testo "pre / post" tra parentesi e ho bisogno di una soluzione più intelligente.


Answer #1

Testo al di fuori della parentesi

> x <- c("a(b)jk(p)"  ,"ipq" , "e(ijkl)")
> gsub("\\([^()]*\\)", "", x)
[1] "ajk" "ipq" "e"  

Testo all'interno della parentesi

> x <- c("a(b)jk(p)"  ,"ipq" , "e(ijkl)")
> gsub("(?<=\\()[^()]*(?=\\))(*SKIP)(*F)|.", "", x, perl=T)
[1] "bp"   ""     "ijkl"

Il (?<=\\()[^()]*(?=\\)) corrisponde a tutti i caratteri presenti all'interno delle parentesi e quindi il seguente (*SKIP)(*F) fa fallire la corrispondenza. Ora prova ad eseguire il modello che era appena dopo a | simbolo contro la corda rimanente. Quindi il punto . corrisponde a tutti i caratteri che non sono già saltati. Sostituendo tutti i personaggi abbinati con una stringa vuota si darà solo il testo presente all'interno delle racchette.

> gsub("\\(([^()]*)\\)|.", "\\1", x, perl=T)
[1] "bp"   ""     "ijkl"

Questa espressione regolare catturerebbe tutti i caratteri presenti all'interno delle parentesi e corrisponderebbe a tutti gli altri caratteri. |. o parte aiuta a far combaciare tutti i caratteri rimanenti diversi da quelli catturati. Quindi, sostituendo tutti i caratteri con i caratteri presenti all'interno dell'indice di gruppo 1, otterrai l'output desiderato.


Answer #2

La funzione rm_round nel pacchetto qdapRegex che ho creato è nata per fare questo:

Per prima cosa prenderemo il carico del pacchetto tramite pacman

if (!require("pacman")) install.packages("pacman")
pacman::p_load(qdapRegex)

## Quindi possiamo usarlo per rimuovere ed estrarre le parti che vuoi :

x <-c("a(b)jk(p)", "ipq", "e(ijkl)")

rm_round(x)

## [1] "ajk" "ipq" "e" 

rm_round(x, extract=TRUE)

## [[1]]
## [1] "b" "p"
## 
## [[2]]
## [1] NA
## 
## [[3]]
## [1] "ijkl"

Per condensare b e p usare:

sapply(rm_round(x, extract=TRUE), paste, collapse="")

## [1] "bp"   "NA"   "ijkl"




stringr