#r #regex #gsub #backreference
#r #регулярное выражение #gsub #обратная ссылка
Вопрос:
Допустим, у меня есть некоторый текст :
myF <- "lag.variable.1 1"
Я хотел бы получить для всех подобных выражений следующий результат: lag.variable.2
(то есть заменить 1 1 на фактическую сумму
Следующее, похоже, не работает, похоже, что обратная ссылка не выполняется в бите eval(parse()):
myF<-gsub("(\.\w )\.([0-9] \ [0-9] )",
paste0( "\1." ,eval(parse(text ="\2"))) ,
myF )
Какие — нибудь советы о том , как добиться желаемого результата?
Спасибо!
Ответ №1:
Вот как вы можете использовать свой текущий шаблон с gsubfn
:
library(gsubfn)
x <- " lag.variable0.3 * lag.variable1.1 1 9892"
p <- "(\.\w )\.([0-9] \ [0-9] )"
gsubfn(p, function(n,m) paste0(n, ".", eval(parse(text = m))), x)
# => [1] " lag.variable0.3 * lag.variable1.2 9892"
Обратите внимание , что совпадение передается вызываемому объекту в этом случае , когда переменной присваивается группа 1 n
, а группе 2 присваивается m
. Возвращаемое значение представляет собой объединение содержимого группы 1 .
и eval
отредактированной группы 2.
Примечание. вы можете упростить вызываемую часть, используя регулярное выражение PCRE (добавить perl=TRUE
аргумент) K
, оператор сброса соответствия, который отбрасывает весь текст, сопоставленный до сих пор:
p <- "\.\w \.\K(\d \ \d )"
gsubfn(p, ~ eval(parse(text = z)), x, perl=TRUE)
[1] " lag.variable0.3 * lag.variable1.2 9892"
Вы можете дополнительно улучшить шаблон для поддержки других операндов, заменив \
на [- /*]
и, если вам нужно поддерживать числа дробными частями, замените [0-9]
на \d*\.?\d
:
p <- "(\.\w )\.(\d*\.?\d [- /*]\d*\.?\d )"
## or a PCRE regex:
p <- "\.\w \.\K(\d*\.?\d [- /*]\d*\.?\d )"
Ответ №2:
Мы можем использовать gsubfn
library(gsubfn)
gsubfn("(\d \ \d )", ~ eval(parse(text = x)), myF)
#[1] "lag.variable.2"
gsubfn("\.([0-9] \ [0-9] )", ~ paste0(".", eval(parse(text = x))), myF2)
#[1] "lag.variable0.3 * lag.variable1.2 9892"
Или с помощью str_replace
library(stringr)
str_replace(myF, "(\d \ \d )", function(x) eval(parse(text = x)))
#[1] "lag.variable.2"
Или вариант с strsplit
и paste
v1 <- strsplit(myF, "\.(?=\d)", perl = TRUE)[[1]]
paste(v1[1], eval(parse(text = v1[2])), sep=".")
#[1] "lag.variable.2"
данные
myF <- "lag.variable.1 1"
myF2 <- "lag.variable0.3 * lag.variable1.1 1 9892"
Комментарии:
1. Спасибо! они работают, когда строка символов изолирована, как в примере. Но что, если выражение является частью более длинной строки, такой как » lag.variable. 3 * задержка.переменная.1.1 9892″
2. @satellite42 также неясно, какой из них вы хотите добавить и нужно ли вам также умножение?
3. @satellite42 каков ожидаемый результат для строки, которую вы прокомментировали
4. Мой плохой, второй пример был плохой копипастой. Для исправления у меня есть формулы, подобные второму примеру (» lag.variable0.3 * lag.variable1.1 1 9892 «), Мне нужно, чтобы это стало
" lag.variable0.3 * lag.variable1.2 9892"
. Спасибо за помощь 🙂5. @satellite42 обновил сообщение с помощью
gsubfn