2013-04-25 19 views
10

Poniższy kod działa tak długo, jak before i after ciągi znaków, które nie mają są specjalne do regex:dynamiczny regex w 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)) 

Czy R posiadają funkcję uciec ciągi mają być używane w regexes?

Odpowiedz

5

Zastosowanie \Q...\E otoczyć że verbatim podwzorów:

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

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

co daje:

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

jeszcze lepiej! Nie wiedziałem o '\ Q ... \ E'. Widzę, że przydaje się w wielu miejscach. – dnagirl

+0

Jest to bardzo przydatne! Jeśli nie potrzebujesz "perl = TRUE" do wyrażenia regularnego, nie jest wymagane, aby '\ Q ... \ E' działało. – severin

7

W Perlu jest http://perldoc.perl.org/functions/quotemeta.html za wykonanie dokładnie tego. Jeśli dokument jest poprawny, gdy mówi

Zwraca wartość WYRAŻ z wszystkich znaków ASCII spoza „słowo” odwrotnym ukośnikiem. (Oznacza to, że wszystkie znaki ASCII nie pasujące/[A-Za-z_0-9]/zostaną poprzedzone odwrotnym ukośnikiem w zwrócony ciąg, niezależnie od ustawień regionalnych.)

wtedy można osiągnąć taka sama wykonując:

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

i twój wzór powinien być:

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

Szybka kontrola poprawności:

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

idealne! Przypuszczam, że nie jest to funkcja podstawowa, ponieważ R nie jest zwykle przeznaczona do przetwarzania tekstu. – dnagirl

1

dnagirl taka funkcja istnieje i jest 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)$" 

można po prostu usunąć "^" i "$" od strun, wykonując:

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

Widziałem "glob2rx" zanim opublikowałem swoją odpowiedź. Nie sądzę, że jest to funkcja zadania, spróbuj na przykład takich rzeczy jak 'glob2rx (". * ")'. – flodel

+0

@flodel, jestem świadomy jego ograniczeń. Przez większość czasu to działało dla mnie. Jedynym powodem, dla którego tu pisałem, jest [** ten post Ricardo **] (http://stackoverflow.com/questions/16224620/r-strings-to-regex-appropriate-strings#16224620), gdzie wydaje się, że jego Pytanie jest dokładnym duplikatem tego. Zostałem poproszony o umieszczenie mojego komentarza tutaj jako odpowiedzi. – Arun