将捕获组替换为重复单个字符,同时保留捕获组的长度

时间:2015-05-15 07:25:02

标签: regex r

假设您要将AXA替换为AAA,并将AXXXXXA替换为AAAAAAA

两个X之间基本上有A个字符,且A s的数量合适。

使用gsub()我尝试过:

gsub(x = "AXA", pattern = "(A)(X+)(\\1)", replacement = "\\1\\1\\1")

给出了AAA。但是,无论AAA获得多长时间,它都是X+。如何在输出中访问子组2的长度?

可能与此重复:  Replace repeating character with another repeated character

但是恕我直言,对于一个单独的问题,恕我直言。

1 个答案:

答案 0 :(得分:4)

您有一个固定的替换模式:您在第一组中绑定了A,因此,\\1指的是A。因此,你获得3 As。您需要采用不同的方法:在X之前和A之后替换所有连续的A。可以使用Perl风格的正则表达式:

input = "AXXXA"
gsub("(?:A|(?<!^)\\G)\\KX(?=X*A)", "A", input, perl=TRUE)

demo code的输出:

[1] "AAAAA"

\G强制连续匹配,\K帮助我们切断最初匹配的A(?=X*A)前瞻确保我们在X之前有A个任意数量。

编辑:

这种方法也适用于更长的字符串(here,我们正在用Xyz替换123之间的每个A

input = "123XyzXyzXyz123"
gsub("(?:123|(?<!^)\\G)\\KXyz(?=(?:Xyz)*123)", "A", input, perl=TRUE)

输出:[1] "123AAA123"

编辑2:

要在2 A之间替换任何字母,我们可以使用\p{L}速记字符类来匹配A之前的任何字母:

gsub("(?:A|(?<!^)\\G)\\K\\p{L}(?=\\p{L}*A)", "A", input, perl=TRUE)
=> [1] "XSDFAAAAAA"