gsub 用模式匹配代码而不是特定的字符串变量替换字符串

gsub replacing string with pattern matching code and not specific string variables

我有一长串要标准化的文件。字符串的不同部分由下划线分隔。但是,创建的大量文件在数字(唯一 ID)和单个字母字符之间没有下划线。每个文件的具体变量会有所不同,但模式是相同的。我如何添加_

我试过了gsub。它正确地拾取模式(只更改需要更改的字符串)但替换是模式匹配代码。

x<- c("A12_SITE_1234_J_vvv.csv","A12_SITA_1234J_vvv.csv", "A12_SITE_1678_H_vvv.csv", "A12_SITE_145C_vvv.csv")

z<- gsub(".*[0-9][A-Z]", ".*[0-9]\_[A-Z]", x)

预期结果:

"A12_SITE_1234_J_vvv.csv","A12_SITA_1234_J_vvv.csv", "A12_SITE_1678_H_vvv.csv", "A12_SITE_145_C_vvv.csv"

当前结果:

"A12_SITE_1234_J_vvv.csv" ".*[0-9]_[A-Z]_vvv.csv"   "A12_SITE_1678_H_vvv.csv" ".*[0-9]_[A-Z]_vvv.csv"

我们可以使用正则表达式环顾四周

sub("(?<=[0-9])(?=[A-Z])", "_", x, perl = TRUE)
#[1] "A12_SITE_1234_J_vvv.csv" "A12_SITA_1234_J_vvv.csv" 
#[3] "A12_SITE_1678_H_vvv.csv" "A12_SITE_145_C_vvv.csv" 

或者使用捕获组 ((..)) 将模式捕获为一个组,然后在替换中使用捕获组的反向引用 (\1, \2)

sub("([0-9])([A-Z])", "\1_\2", x, perl = TRUE)

在 OP 的代码中,未捕获模式 .*(任何字符)后跟数字 ([0-9]) 和字母表 ([A-Z]),因此它丢失了在更换。此外,在替换中,如果我们使用 [0-9],它将被视为文字字符串

在替换模式中使用capturing group with backrefences(注意替换模式不能是正则表达式模式,您只使用正则表达式来搜索一些文本):

> sub("(.*[0-9])([A-Z])", "\1_\2", x)
[1] "A12_SITE_1234_J_vvv.csv" "A12_SITA_1234_J_vvv.csv" "A12_SITE_1678_H_vvv.csv" "A12_SITE_145_C_vvv.csv" 

参见R online demo and the regex demo

图案详情

  • (.*[0-9])- 第 1 组 (</code>):任何 0+ 个字符,尽可能多,最多包含一个数字 </li> <li><code>([A-Z]) - 第 2 组 ():大写 ASCII 字母。