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 字母。
我有一长串要标准化的文件。字符串的不同部分由下划线分隔。但是,创建的大量文件在数字(唯一 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 字母。