2013-04-25 2 views
10

Приведенный ниже код работает так долго, как before и after струны не имеют символов, которые являются особенными для регулярных выражений:динамическое регулярное выражение в 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)) 

ли R есть функция, чтобы избежать строк, которые будут использоваться в регулярных выражений?

ответ

5

Использование \Q...\E окружать стенографические подмасками:

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

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

, который дает:

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

еще лучше! Я не знал о '\ Q ... \ E'. Я вижу, что это пригодится во многих местах. – dnagirl

+0

Это очень удобно! Если вам не нужно 'perl = TRUE' для вашего регулярного выражения, это не является обязательным условием для' \ Q ... \ E'. – severin

7

В Perl есть http://perldoc.perl.org/functions/quotemeta.html для выполнения именно этого. Если документ является правильным, когда он говорит

Возвращает значение EXPR со всей ASCII не- «слово» символами управляющих последовательностями. (То есть, все символы ASCII не соответствуют/[A-Za-z_0-9]/будет предшествовать обратная косая черта в возвращаемой строке, независимо от настроек локали.)

, то вы можете достичь то же самое, выполнив:

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

И ваша модель должна быть:

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

Быстрая проверка исправности:

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

безупречный! Я полагаю, что это не основная функция, потому что R обычно не предназначена для обработки текста. – dnagirl

1

dnagirl, такая функция существует и 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)$" 

Вы можете просто удалить "^" и "$" из строки, выполнив:

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

Я видел 'glob2rx', прежде чем отправил свой ответ. Я не думаю, что это функция для задачи, например, «glob2rx («. * »)». – flodel

+0

@flodel, я знаю его ограничения. Большую часть времени это работало для меня. Единственная причина, по которой я разместил здесь, - это [** это сообщение Рикардо **] (http://stackoverflow.com/questions/16224620/r-strings-to-regex-appro-strings#16224620), где кажется, что его вопрос является точным дубликатом этого ... и меня попросили опубликовать мой комментарий здесь в качестве ответа. – Arun

Смежные вопросы