2013-04-25 9 views
10

Il seguente codice funziona fintanto che before e after stringhe hanno caratteri che sono speciali per una regex:regex dinamica R

before <- 'Name of your Manager (note "self" if you are the Manager)' #parentheses cause problem in regex 
after <- 'CURRENT FOCUS' 

pattern <- paste0(c('(?<=', before, ').*?(?=', after, ')'), collapse='') 
ex <- regmatches(x, gregexpr(pattern, x, perl=TRUE)) 

Ha R ha una funzione per sfuggire stringhe da utilizzare in espressioni regolari?

risposta

5

Usa \Q...\E a circondare le sottopattern testualmente:

# test data 
before <- "A." 
after <- ".Z" 
x <- c("A.xyz.Z", "ABxyzYZ") 

pattern <- sprintf('(?<=\\Q%s\\E).*?(?=\\Q%s\\E)', before, after) 

che dà:

> gregexpr(pattern, x, perl = TRUE) > 0 
[1] TRUE FALSE 
+0

ancora meglio! Non ero a conoscenza di '\ Q ... \ E'. Posso vederlo tornare utile in molti posti. – dnagirl

+0

Questo è molto utile! Se non hai bisogno di 'perl = TRUE' per la tua regex, non è un requisito per' \ Q ... \ E' funzionare. – severin

7

In Perl, c'è http://perldoc.perl.org/functions/quotemeta.html per fare esattamente questo. Se il documento è corretta quando dice

Restituisce il valore di ESPR con tutte le ASCII non caratteri "parola" backslash. (Cioè, tutti i caratteri ASCII che non corrisponde/[A-Za-z_0-9]/saranno preceduti da un backslash nella stringa restituita, indipendentemente da eventuali impostazioni locali.)

allora si può raggiungere lo stesso facendo:

quotemeta <- function(x) gsub("([^A-Za-z_0-9])", "\\\\\\1", x) 

E il vostro modello dovrebbe essere:

pattern <- paste0(c('(?<=', quotemeta(before), ').*?(?=', quotemeta(after), ')'), 
        collapse='') 

controllo di integrità rapida:

a <- "he'l(lo)" 
grepl(a, a) 
# [1] FALSE 
grepl(quotemeta(a), a) 
# [1] TRUE 
+0

perfetto! Suppongo che non sia una funzione di base perché R non è di solito inteso per l'elaborazione del testo. – dnagirl

1

dnagirl, una tale funzione esiste ed è glob2rx

a <- "he'l(lo)" 
tt <- glob2rx(a) 
# [1] "^he'l\\(lo)$" 

before <- 'Name of your Manager (note "self" if you are the Manager)' 
tt <- glob2rx(before) 
# [1] "^Name of your Manager \\(note \"self\" if you are the Manager)$" 

Si può solo rimuovere il "^" e "$" dalle corde facendo:

substr(tt, 2, nchar(tt)-1) 
# [1] "he'l\\(lo)" 
+0

Ho visto 'glob2rx' prima di pubblicare la mia risposta. Non penso che sia la funzione per il compito, prova cose come 'glob2rx (". * ")' Per esempio. – flodel

+0

@flodel, sono a conoscenza dei suoi limiti. Il più delle volte ha funzionato per me. L'unica ragione per cui ho postato qui è a causa di [** questo post di Ricardo **] (http://stackoverflow.com/questions/16224620/r-strings-to-regex-appropriate-strings#16224620) dove sembra che il suo la domanda è un duplicato esatto di questo .. e mi è stato chiesto di postare il mio commento qui come risposta. – Arun