Вы можете захватить то, что вам нужно сохранить, и просто сопоставить то, что вам нужно заменить, используйте
> gsub("(#[^ \t#]+ )[^#]*(#)", "\\1REPLACED WITH THIS\\2", text)
[1] "My code #snippet REPLACED WITH THIS# is simple"
Подробности
(#[^ \t#]+ )
- Группа 1: #
, затем любые 1+ символов, кроме #
, пробел и табуляция и пробел [^#]*
- 0+ символов, кроме #
(#)
- группа 2: a #
char
Другой способ: используйте gsubfn
с шаблоном, в котором все части шаблона объединены в отдельные группы, а затем восстановите замену после выполнения необходимых манипуляций. :
> gsubfn::gsubfn("(#[^ \t#]+ )([^#]*)(#)", function(x, y, z) paste0(x, "REPLACED WITH THIS", z), text)
[1] "My code #snippet REPLACED WITH THIS# is simple"
Здесь x
, y
и z
относятся к группам, определенным в шаблоне:
(#[^ \t#]+ )([^#]*)(#)
| --- x ---||- y -||z|
С stringr
вы можете - но вы должны быть очень осторожны с этим - используйте шаблон с lookbehind / lookahead:
> stringr::str_replace_all(text, "(?<=#[^ \t#]{1,1000} )[^#]*(?=#)", "REPLACED WITH THIS")
[1] "My code #snippet REPLACED WITH THIS# is simple"
Lookbehind (?<=#[^ \t#]{1,1000} )
работает, потому что он соответствует известной длине шаблон ({1,1000}
говорит, что может быть от 1 до 1000 вхождений любых символов, кроме пробела, табуляции и #
), и это " ограниченная ширина lo поддерживается okbehind", поскольку stringr
использует библиотеку регулярных выражений ICU .