R Language
Espressioni regolari (regex)
Ricerca…
introduzione
Le espressioni regolari (dette anche "regex" o "regexp") definiscono pattern che possono essere abbinati a una stringa . Digitare ?regex
per la documentazione ufficiale R e consultare il documento Regex per maggiori dettagli. Il più importante 'gotcha' che non verrà appreso nella regex / topics di SO è che la maggior parte delle funzioni di R-regex richiedono l'uso di backslash accoppiati per l'escape in un parametro di pattern
.
Osservazioni
Classi di caratteri
-
"[AB]"
potrebbe essere A o B -
"[[:alpha:]]"
potrebbe essere qualsiasi lettera -
"[[:lower:]]"
sta per qualsiasi lettera minuscola. Nota che"[az]"
è vicino ma non corrisponde, ad esempio,ú
. -
"[[:upper:]]"
sta per qualsiasi lettera maiuscola. Nota che"[AZ]"
è vicino ma non corrisponde, ad esempio,Ú
. -
"[[:digit:]]"
indica qualsiasi cifra: 0, 1, 2, ... o 9 ed è equivalente a"[0-9]"
.
quantificatori
+
, *
e ?
applicare come al solito in regex. - +
corrisponde almeno una volta, *
corrisponde a 0 o più volte e ?
corrisponde a 0 o 1 volta.
Indicatori di inizio e fine linea
È possibile specificare la posizione della regex nella stringa:
-
"^..."
forza l'espressione regolare all'inizio della stringa -
"...$"
forza l'espressione regolare alla fine della stringa
Differenze da altre lingue
Tieni presente che le espressioni regolari in R spesso appaiono leggermente diverse dalle espressioni regolari utilizzate in altre lingue.
R richiede due escape backslash (poiché
"\"
implica già l'escape in generale nelle stringhe R), quindi, per esempio, per catturare spazi bianchi nella maggior parte dei motori di espressioni regolari, è sufficiente digitare\s
, contro\\s
in R .I caratteri UTF-8 in R devono essere sottoposti a escape con una U maiuscola, ad es.
[\U{1F600}]
e[\U1F600]
corrispondono 😀, mentre in, ad esempio, Ruby, questo verrà confrontato con u minuscole.
Risorse addizionali
Il seguente sito reg101 è un buon posto per controllare la regex online prima di utilizzarlo R-script.
The R Programmming wikibook ha una pagina dedicata all'elaborazione del testo con molti esempi usando le espressioni regolari.
Eliminare gli spazi bianchi
string <- ' some text on line one;
and then some text on line two '
Taglio spazio bianco
Gli spazi bianchi di "ritaglio" si riferiscono in genere alla rimozione di spazi bianchi iniziali e finali da una stringa. Questo può essere fatto usando una combinazione degli esempi precedenti. gsub
è usato per forzare la sostituzione su entrambe le partite gsub
e finali.
Prima di R 3.2.0
gsub(pattern = "(^ +| +$)",
replacement = "",
x = string)
[1] "some text on line one; \nand then some text on line two"
R 3.2.0 e versioni successive
trimws(x = string)
[1] "some text on line one; \nand then some text on line two"
Rimozione degli spazi bianchi iniziali
Prima di R 3.2.0
sub(pattern = "^ +",
replacement = "",
x = string)
[1] "some text on line one; \nand then some text on line two "
R 3.2.0 e versioni successive
trimws(x = string,
which = "left")
[1] "some text on line one; \nand then some text on line two "
Rimozione spazi bianchi finali
Prima di R 3.2.0
sub(pattern = " +$",
replacement = "",
x = string)
[1] " some text on line one; \nand then some text on line two"
R 3.2.0 e versioni successive
trimws(x = string,
which = "right")
[1] " some text on line one; \nand then some text on line two"
Rimozione di tutti gli spazi bianchi
gsub(pattern = "\\s",
replacement = "",
x = string)
[1] "sometextonlineone;andthensometextonlinetwo"
Si noti che questo rimuoverà anche i caratteri dello spazio bianco come i tab ( \t
), i newline ( \r
e \n
) e gli spazi.
Convalida una data in un formato "AAAAMMGG"
È prassi comune denominare i file utilizzando la data come prefisso nel formato seguente: YYYYMMDD
, ad esempio: 20170101_results.csv
. Una data in tale formato di stringa può essere verificata utilizzando la seguente espressione regolare:
\\d{4}(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01])
L'espressione di cui sopra considera risale anno: 0000-9999
, mesi tra: 01-12
e giorni 01-31
.
Per esempio:
> grepl("\\d{4}(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01])", "20170101")
[1] TRUE
> grepl("\\d{4}(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01])", "20171206")
[1] TRUE
> grepl("\\d{4}(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01])", "29991231")
[1] TRUE
Nota : convalida la sintassi della data, ma possiamo avere una data errata con una sintassi valida, ad esempio: 20170229
(2017 non è un anno bisestile).
> grepl("\\d{4}(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01])", "20170229")
[1] TRUE
Se si desidera convalidare una data, è possibile farlo tramite questa funzione definita dall'utente:
is.Date <- function(x) {return(!is.na(as.Date(as.character(x), format = '%Y%m%d')))}
Poi
> is.Date(c("20170229", "20170101", 20170101))
[1] FALSE TRUE TRUE
Convalidare le abbreviazioni postali degli Stati Uniti
La seguente regex
include 50 stati e anche Commonwealth / Territorio (vedi www.50states.com ):
regex <- "(A[LKSZR])|(C[AOT])|(D[EC])|(F[ML])|(G[AU])|(HI)|(I[DLNA])|(K[SY])|(LA)|(M[EHDAINSOT])|(N[EVHJMYCD])|(MP)|(O[HKR])|(P[WAR])|(RI)|(S[CD])|(T[NX])|(UT)|(V[TIA])|(W[AVIY])"
Per esempio:
> test <- c("AL", "AZ", "AR", "AJ", "AS", "DC", "FM", "GU","PW", "FL", "AJ", "AP")
> grepl(us.states.pattern, test)
[1] TRUE TRUE TRUE FALSE TRUE TRUE TRUE TRUE TRUE TRUE FALSE FALSE
>
Nota :
Se si desidera verificare solo i 50 stati, si consiglia di utilizzare il set di dati R: state.abb
dallo state
, ad esempio:
> data(state)
> test %in% state.abb
[1] TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE TRUE FALSE FALSE
Otteniamo TRUE
solo per le abbreviazioni di 50 Stati: AL, AZ, AR, FL
.
Convalidare i numeri di telefono degli Stati Uniti
La seguente espressione regolare:
us.phones.regex <- "^\\s*(\\+\\s*1(-?|\\s+))*[0-9]{3}\\s*-?\\s*[0-9]{3}\\s*-?\\s*[0-9]{4}$"
Convalida un numero di telefono sotto forma di: +1-xxx-xxx-xxxx
, compresi spazi vuoti iniziali / finali opzionali all'inizio / alla fine di ciascun gruppo di numeri, ma non nel mezzo, ad esempio: +1-xxx-xxx-xx xx
non è valido. L' -
delimitatore può essere sostituito da spazi: xxx xxx xxx
o senza delimitatore: xxxxxxxxxx
. Il prefisso +1
è facoltativo.
Controlliamolo:
us.phones.regex <- "^\\s*(\\+\\s*1(-?|\\s+))*[0-9]{3}\\s*-?\\s*[0-9]{3}\\s*-?\\s*[0-9]{4}$"
phones.OK <- c("305-123-4567", "305 123 4567", "+1-786-123-4567",
"+1 786 123 4567", "7861234567", "786 - 123 4567", "+ 1 786 - 123 4567")
phones.NOK <- c("124-456-78901", "124-456-789", "124-456-78 90",
"124-45 6-7890", "12 4-456-7890")
Casi validi:
> grepl(us.phones.regex, phones.OK)
[1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE
>
Casi non validi:
> grepl(us.phones.regex, phones.NOK)
[1] FALSE FALSE FALSE FALSE FALSE
>
Nota :
-
\\s
Trova qualsiasi spazio, tab o carattere di fine riga
Escaping di caratteri nei pattern di regex di R
Poiché sia R che regex condividono il carattere di escape, "\"
, la creazione di schemi corretti per grep
, sub
, gsub
o qualsiasi altra funzione che accetta un argomento di pattern spesso richiede l'associazione di barre rovesciate. Se si costruisce un vettore di caratteri di tre elementi in cui un elemento ha un avanzamento di riga, un altro un carattere di tabulazione e uno nessuno, e il desiderio è di trasformare il linefeed o il tab in 4 spazi, allora è necessario un singolo backslash per la costruzione, ma i backslash tpaired per la corrispondenza:
x <- c( "a\nb", "c\td", "e f")
x # how it's stored
# [1] "a\nb" "c\td" "e f"
cat(x) # how it will be seen with cat
#a
#b c d e f
gsub(patt="\\n|\\t", repl=" ", x)
#[1] "a b" "c d" "e f"
Si noti che l'argomento pattern (che è opzionale se appare per primo e richiede solo l'ortografia parziale) è l'unico argomento per richiedere questo raddoppiamento o accoppiamento. L'argomento sostitutivo non richiede il raddoppio dei caratteri che devono essere sfuggiti. Se si desidera che tutti i ritorni di riga e le sostituzioni di 4 spazi sostituiscano con le schede, sarebbe:
gsub("\\n| ", "\t", x)
#[1] "a\tb" "c\td" "e\tf"
Differenze tra regix di Perl e POSIX
Esistono due motori di espressioni regolari, sempre leggermente differenti, implementati in R. L'impostazione predefinita è definita POSIX; tutte le funzioni regex in R sono inoltre dotate di un'opzione per attivare quest'ultimo tipo: perl = TRUE
.
Look-ahead / look-dietro
perl = TRUE
abilita look-ahead e look-behind nelle espressioni regolari.
-
"(?<=A)B"
corrisponde a un aspetto della letteraB
solo se è preceduto daA
, vale a dire"ABACADABRA"
verrebbe abbinato, ma"abacadabra"
e"aBacadabra"
non lo sarebbero.