r - 如何找到特定字符两侧的子字符串并替换为 R 中相同长度的文本?

标签 r regex

在 R 中,找到两侧有星号的点并将其替换为星号的最佳方法是什么?

输入:

“AG**...**GG*.*.G.*C.C”

期望的输出:

“AG*******GG***.G.*C.C”

我尝试了下面的功能,但至少可以说是不够优雅。

    library(stringr)

    replac <- function(my_string) {

        m <- str_locate_all(my_string, "\\*\\.+\\*")[[1]]

        if (nrow(m) == 0) return(my_string)

        split_s <- unlist(str_split(my_string, "")) 

        for (i in 1:nrow(m)) {
            st <- m[i, 1]
            en <- m[i, 2] 
            split_s[st:en] <- rep("*", length(st:en))
        }

        paste(split_s, collapse = "")
    }
  • 我已经在@TheForthBird 回答下面的问题后编辑了输入字符串和预期输出,以明确不应该更改两侧没有星号的点,并且可能出现其他字母以及“A”和“G”。

最佳答案

您可以将 gsub 与 perl = TRUE 一起使用,并使用 \G anchor 断言上一个匹配项结束时的位置。

您可以使用字符类 [AG]G[A-Z]+ 匹配 AG 或 GG 以匹配 1+ 个大写字符。

在替换中使用*

(?:[A-Z]+\*+|\G(?!^))\K\.(?=[^*]*\*)

那将匹配

  • (?: 非捕获组
  • [A-Z]+*+匹配 1+ 次大写字符 A-Z,然后匹配 1+ 次*`
    • | 或者
    • \G(?!^) 在上一场比赛结束时断言位置,而不是在开始处
  • ) 关闭非捕获组
  • \K 忘记当前匹配的是什么
  • \. 字面匹配
  • (?= 正面前瞻,断言右边的是
    • [^*]*\* 匹配除*以外的任意字符0+次,然后匹配*
  • ) 关闭前瞻

Regex demo | R demo

例如:

gsub("(?:[A-Z]+\\*+|\\G(?!^))\\K\\.(?=[^*]*\\*)", "*", "AG**...**GG*.*.G.*C.C", perl = TRUE)

结果

[1] "AG*******GG***.G.*C.C"

关于r - 如何找到特定字符两侧的子字符串并替换为 R 中相同长度的文本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57631833/

相关文章:

r - 在运行时在 lapply 包装器中打印消息

r - 将组 ID 分配给时间序列中连续唯一值的序列

php - 变量和 preg_match PHP

regex - awk 正则表达式在尝试查找重复数字时无法匹配 ip 地址

Java 正则表达式模式匹配所有语言中以空格结尾的字符串

regex - 使用 awk 脚本在两种模式之间拉取文本

r - 更改脱脂打印汇总函数的顺序

r - 使用 dplyr 以可变时间间隔过滤

css - 具有动态高度的 Shiny 渲染图

java - 什么合适的正则表达式可以排除某个单词