Динамическое регулярное выражение в R
Следующий код работает, пока строки before
и after
не имеют символов, которые являются особыми для регулярного выражения:
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 функция для удаления строк, которые будут использоваться в регулярных выражениях?
Ответы
Ответ 1
Используйте \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
Ответ 2
В 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
Ответ 3
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)"