R Language
Pattern Matching and Replacement
Ricerca…
introduzione
Questo argomento copre i modelli di stringhe corrispondenti, così come l'estrazione o la sostituzione. Per dettagli sulla definizione di modelli complicati vedere Espressioni regolari .
Sintassi
grep ("query", "subject", optional_args)
grepl ("query", "subject", optional_args)
gsub ("(gruppo1) (gruppo2)", "\\ gruppo #", "oggetto")
Osservazioni
Differenze da altre lingue
Escape regex simboli (come \1
) sono devono essere preceduti una seconda volta (come \\1
), non solo nel pattern
argomentazione, ma anche in replacement
di sub
e gsub
.
Per impostazione predefinita, il pattern per tutti i comandi (grep, sub, regexpr) non è Perl Compatible Regular Expression (PCRE) quindi alcune cose come i lookaround non sono supportate. Tuttavia, ogni funzione accetta un argomento perl=TRUE
per attivarli. Vedi l' argomento R Regular Expressions per i dettagli.
Pacchetti specializzati
- stringi
- stringr
Fare sostituzioni
# example data
test_sentences <- c("The quick brown fox quickly", "jumps over the lazy dog")
Facciamo la volpe marrone rossa:
sub("brown","red", test_sentences)
#[1] "The quick red fox quickly" "jumps over the lazy dog"
Ora, facciamo in modo che la "fast"
volpe agisca "fastly"
. Questo non lo farà:
sub("quick", "fast", test_sentences)
#[1] "The fast red fox quickly" "jumps over the lazy dog"
sub
fa solo la prima sostituzione disponibile, abbiamo bisogno di gsub
per la sostituzione globale :
gsub("quick", "fast", test_sentences)
#[1] "The fast red fox fastly" "jumps over the lazy dog"
Vedi Modifica di stringhe per sostituzione per altri esempi.
Trovare le partite
# example data
test_sentences <- c("The quick brown fox", "jumps over the lazy dog")
C'è una partita?
grepl()
è usato per verificare se esiste una parola o un'espressione regolare in una stringa o in un vettore di caratteri. La funzione restituisce un vettore TRUE / FALSE (o "Boolean").
Si noti che possiamo controllare ogni stringa per la parola "volpe" e ricevere in cambio un vettore booleano.
grepl("fox", test_sentences)
#[1] TRUE FALSE
Abbina le posizioni
grep
una stringa di caratteri e un'espressione regolare. Restituisce un vettore numerico di indici. Ciò restituirà in quale frase è contenuta la parola "volpe".
grep("fox", test_sentences)
#[1] 1
Valori abbinati
Per selezionare frasi che corrispondono a un modello:
# each of the following lines does the job:
test_sentences[grep("fox", test_sentences)]
test_sentences[grepl("fox", test_sentences)]
grep("fox", test_sentences, value = TRUE)
# [1] "The quick brown fox"
Dettagli
Poiché il modello "fox"
è solo una parola, piuttosto che un'espressione regolare, potremmo migliorare le prestazioni (con grep
o grepl
) specificando fixed = TRUE
.
grep("fox", test_sentences, fixed = TRUE)
#[1] 1
Per selezionare frasi che non corrispondono a un modello, si può usare grep
con invert = TRUE
; o seguire subsetting regole con -grep(...)
o !grepl(...)
.
In entrambi grepl(pattern, x)
e grep(pattern, x)
, il parametro x
è vettorizzato , il parametro pattern
non lo è. Di conseguenza, non è possibile utilizzarli direttamente per abbinare il pattern[1]
x[1]
, il pattern[2]
x[2]
e così via.
Riepilogo delle partite
Dopo aver eseguito ad es. grepl
comando grepl
, forse vuoi avere una panoramica su quante partite sono TRUE
o FALSE
. Questo è utile ad esempio in caso di grandi set di dati. Per farlo, esegui il comando di summary
:
# example data
test_sentences <- c("The quick brown fox", "jumps over the lazy dog")
# find matches
matches <- grepl("fox", test_sentences)
# overview
summary(matches)
Partita singola e globale.
Quando si lavora con espressioni regolari, un modificatore per PCRE è g
per la corrispondenza globale.
Nelle funzioni di corrispondenza e sostituzione R sono disponibili due versioni: prima corrispondenza e corrispondenza globale:
sub(pattern,replacement,text)
sostituirà la prima occorrenza del pattern sostituendola nel testogsub(pattern,replacement,text)
farà lo stesso di sub ma per ogni occorrenza di patternregexpr(pattern,text)
restituirà la posizione di match per la prima istanza di patterngregexpr(pattern,text)
restituirà tutte le corrispondenze.
Alcuni dati casuali:
set.seed(123)
teststring <- paste0(sample(letters,20),collapse="")
# teststring
#[1] "htjuwakqxzpgrsbncvyo"
Vediamo come funziona se vogliamo sostituire le vocali con qualcos'altro:
sub("[aeiouy]"," ** HERE WAS A VOWEL** ",teststring)
#[1] "htj ** HERE WAS A VOWEL** wakqxzpgrsbncvyo"
gsub("[aeiouy]"," ** HERE WAS A VOWEL** ",teststring)
#[1] "htj ** HERE WAS A VOWEL** w ** HERE WAS A VOWEL** kqxzpgrsbncv ** HERE WAS A VOWEL** ** HERE WAS A VOWEL** "
Ora vediamo come possiamo trovare una consonante immediatamente seguita da una o più vocali:
regexpr("[^aeiou][aeiou]+",teststring)
#[1] 3
#attr(,"match.length")
#[1] 2
#attr(,"useBytes")
#[1] TRUE
Abbiamo una corrispondenza sulla posizione 3 della stringa di lunghezza 2, ovvero: ju
Ora se vogliamo ottenere tutte le partite:
gregexpr("[^aeiou][aeiou]+",teststring)
#[[1]]
#[1] 3 5 19
#attr(,"match.length")
#[1] 2 2 2
#attr(,"useBytes")
#[1] TRUE
Tutto questo è davvero grandioso, ma questo solo da usare posizioni di match e non è così facile ottenere ciò che è abbinato, e qui arrivano regmatches
cui unico scopo è estrarre la stringa corrispondente da regexpr, ma ha una sintassi diversa.
Salviamo le nostre corrispondenze in una variabile e quindi estraetele dalla stringa originale:
matches <- gregexpr("[^aeiou][aeiou]+",teststring)
regmatches(teststring,matches)
#[[1]]
#[1] "ju" "wa" "yo"
Può sembrare strano non avere una scorciatoia, ma questo permette di estrarre da un'altra stringa le corrispondenze del nostro primo (pensa che confrontare due lunghi vettori in cui sai che c'è un modello comune per il primo ma non per il secondo, questo permette un facile confronto):
teststring2 <- "this is another string to match against"
regmatches(teststring2,matches)
#[[1]]
#[1] "is" " i" "ri"
Nota di attenzione: per impostazione predefinita il pattern non è un'espressione regolare compatibile con Perl, alcune cose come i lookaround non sono supportate, ma ogni funzione qui presentata consente perl=TRUE
argomento di abilitarle.
Trova le partite in grandi set di dati
In caso di grandi set di dati, la chiamata di grepl("fox", test_sentences)
non ha un buon grepl("fox", test_sentences)
. I grandi insiemi di dati sono ad esempio siti Web sottoposti a scansione o milioni di tweet, ecc.
La prima accelerazione è l'uso dell'opzione perl = TRUE
. Ancora più veloce è l'opzione fixed = TRUE
. Un esempio completo potrebbe essere:
# example data
test_sentences <- c("The quick brown fox", "jumps over the lazy dog")
grepl("fox", test_sentences, perl = TRUE)
#[1] TRUE FALSE
In caso di text mining, spesso viene utilizzato un corpus. Un corpus non può essere utilizzato direttamente con grepl
. Pertanto, considera questa funzione:
searchCorpus <- function(corpus, pattern) {
return(tm_index(corpus, FUN = function(x) {
grepl(pattern, x, ignore.case = TRUE, perl = TRUE)
}))
}