首页 > 解决方案 > 字符串替换忽略字符

问题描述

我有以下字符串:

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. 

所以我正在寻找一种方法来匹配忽略 <> 字符的子字符串。

标签: rregexgsubstringrstringi

解决方案


放置[<>]*在连续字符之间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>"

推荐阅读