Заменить строку с игнорированием символов

У меня есть следующая строка:

string <- c("ABDSFGHIJLKOP")

и список подстрок:

sub <- c("ABDSF", "SFGH", "GHIJLKOP")

Я хотел бы включить ‹ и > после каждого дополнительного совпадения, получив таким образом:

<ABD><SF><GH><GHIJKOP>

Я попробовал следующий код путем сопоставления с образцом по списку, но как только ABDSF сопоставляется, SFGH больше не распознается из-за включения символов ‹>. У кого-нибудь есть идея получше?

library(stringr)
library(dplyr)
library(magrittr)

string <- c("ABDSFGHIJLKOP")
sub <- c("ABDSF", "SFGH", "GHIJLKOP")

for (s in sub){

string %<>% str_replace_all(., s, paste0('<', s,'>'))
}

print(string)


Result: [1] "<ABDSF><GHIJLKOP>"

РЕДАКТИРОВАТЬ: Проблема, с которой я сталкиваюсь в приведенном выше коде, заключается в том, что как только вставляются символы ‹>, после совпадения первой строки вторая строка SFGH больше не распознается, потому что теперь строка:

 <ABDSF>GHIJLKOP. 

Поэтому я ищу способ сопоставить подстроки, игнорируя символы ‹>.


person Nivel    schedule 28.12.2018    source источник
comment
Я не понимаю, как вы получаете ожидаемый результат. Можете ли вы уточнить немного больше, пожалуйста?   -  person Sotos    schedule 28.12.2018
comment
Возможный дубликат Вставьте символ в определенное место в строка   -  person NelsonGon    schedule 28.12.2018
comment
Не совсем дубликат выше   -  person Sotos    schedule 28.12.2018
comment
Посмотрите на третий последний ответ (от Зака ​​​​Фостера) в этом вопросе. Может помочь.   -  person NelsonGon    schedule 28.12.2018
comment
Использование функции в указанном вопросе. Вы можете использовать его по своему усмотрению: insert_str(mystring,c("<",">"),c(0,4)) дает: ‹ABD›SFGHIJLKOP   -  person NelsonGon    schedule 28.12.2018
comment
не должен ли ожидаемый результат быть: <ABDSF><SFGH><GHIJKOP> ?   -  person Shique    schedule 28.12.2018
comment
Да. Я просто использовал образец индекса. OP может индексировать все значения по своему усмотрению. Конечно, для очень длинных строк это будет утомительно, но это только начало.   -  person NelsonGon    schedule 28.12.2018
comment
Ах, на самом деле я имел в виду ОП, его ожидаемый результат не соответствует его критериям, поэтому я немного запутался.   -  person Shique    schedule 28.12.2018
comment
мне жаль, что я не могу написать код в r, но вы можете попробовать выполнить цикл для каждой подстроки в ваших элементах (вы делаете это), но объединить результаты без изменения вашей строковой переменной   -  person lagripe    schedule 28.12.2018


Ответы (2)


Поместите [<>]* между последовательными символами в sub, а затем выполните подстановки с этими шаблонами. Пакеты не используются.

# test input
string <- "ABDSFGHIJLKOP"
subs <- c("ABDSF", "SFGH", "GHIJLKOP")

pats <- paste0("(", gsub("(?<=[EF])(.)(?=.)", "\\1[<>]*", subs, perl = TRUE), ")")
s <- string
for(p in pats) s <- gsub(p, "<\\1>", s)
s
## [1] "<ABD<SF><GH>IJLKOP>"

Обновлять

Что касается комментария ниже, если я правильно понимаю, мы могли бы добавить (?<=[EF]) предоставление:

pats <- paste0("(", gsub("(?<=[EF])(.)(?=.)", "\\1[<>]*", subs, perl = TRUE), ")")
s <- string
for(p in pats) s <- gsub(p, "<\\1>", s)
s
## [1] "<ABDSF><GHIJLKOP>"
person G. Grothendieck    schedule 28.12.2018
comment
В любом случае, вы могли бы добавить условное выражение? Например, добавляйте ‹› только тогда, когда предшествующий символ является буквой E или F? Таким образом, SFGH не будет соответствовать, потому что предыдущий символ — это D, а не E или F. - person Nivel; 23.01.2019
comment
Большое спасибо за вашу помощь, это действительно ценится! Проблема, которая у меня все еще есть, заключается в том, что это не работает, если вы, например, хотите исключить GHIJLKOP, изменив [EF] на [E]. Результат = ‹ABDSF›‹GHIJLKOP›. Я ищу ‹ABDSF›GHIJLKOP. - person Nivel; 24.01.2019

#R version 3.3.2 

library(stringr)
library(magrittr)

string <- c("ABDSFGHIJLKOP")
sub <- c("ABDSF", "SFGH", "GHIJLKOP")
result <- c("")
for (s in sub){
temp<- c(str_extract(string, s))
if (!is.null(temp)) {
        temp<- paste("<",temp,">",sep = "")
        result <- paste(result,temp,sep = "")

    }
}
print(result)

Результат :

[1] "<ABDSF><SFGH><GHIJLKOP>"

Протестировано в Rextester

person lagripe    schedule 28.12.2018