R Regex识别和替换多个点之间的字符
R Regex to identify and replace characters between multiple dots
我有以下代码
"ABC.A.SVN.10.10.390.10.UDGGL"
"XYZ.Z.SVN.11.12.111.99.ASDDL"
我需要替换第二个和第三个点之间的字符。在这种情况下它是 SVN
但它很可能是 A
和 ZZZ
之间的任意组合,因此真正实现此目的的唯一方法是使用点。
要求的结果是:
"ABC.A..10.10.390.10.UDGGL"
"XYZ.Z..11.12.111.99.ASDDL"
我尝试了 grep("^.+(\.\).$", "ABC.A.SVN.10.10.390.10.UDGGL")
的变体,但出现错误。
一些我尝试过但没有成功的例子:
Link 1
Link 2
编辑
我尝试了@Onyambu 的第一种方法,然后 运行 变成了一个我没有考虑过的变体:"ABC.A.AB11.1.12.112.1123.UDGGL"
。在替换部分,我也有数值。期望的结果是 "ABC.A..1.12.112.1123.UDGGL"
我在他回答的第二部分使用 sub("\.\w+.\B.",".",x)
得到它!
x= "ABC.A.SVN.10.10.390.10.UDGGL" "XYZ.Z.SVN.11.12.111.99.ASDDL"
sub("([A-Z]+)(\.\d+)","\2",x)
[1] "ABC.A..10.10.390.10.UDGGL" "XYZ.Z..11.12.111.99.ASDDL"
([A-Z]+)
捕获任何包含字符 A-Z 的单词
(\.\d+)
上面捕获的单词必须跟一个点,即\.
。这个点后面跟着数字,即\d+
。这样就完成了捕获。
到目前为止,字符串 "ABC.A.SVN.10.10.390.10.UDGGL"
的捕获部分是 SVN.10
,因为这是匹配正则表达式的部分。但是这部分被捕获为SVN
和.10
。我们做一个反向引用,即将整个 SVN.10
替换为第二部分 .10
另一个可行的逻辑:
sub("\.\w+.\B.",".",x)
[1] "ABC.A..10.10.390.10.UDGGL" "XYZ.Z..11.12.111.99.ASDDL"
x <- c("ABC.A.SVN.10.10.390.10.UDGGL", "XYZ.Z.SVN.11.12.111.99.ASDDL")
sub("^(?:[^.]*\.){2}\K[^.]*", "", x, perl=T)
^
在行首声明位置
(?:[^.]*\.){2}
恰好匹配以下两次
[^.]*\.
匹配除 .
以外的任何字符任意次数,后跟 .
\K
重置模式的起点。任何先前消耗的字符不再包含在最终匹配中
[^.]*
匹配除 .
之外的任何字符任意次数
结果 [1] "ABC.A..10.10.390.10.UDGGL" "XYZ.Z..11.12.111.99.ASDDL"
不完全是正则表达式,但这是另一种方法
#DATA
S = c("ABC.A.SVN.10.10.390.10.UDGGL", "XYZ.Z.SVN.11.12.111.99.ASDDL")
sapply(X = S,
FUN = function(str){
ind = unlist(gregexpr("\.", str))[2:3]
paste(c(substring(str, 1, ind[1]),
"SUBSTITUTION",
substring(str, ind[2], )), collapse = "")
},
USE.NAMES = FALSE)
#[1] "ABC.A.SUBSTITUTION.10.10.390.10.UDGGL" "XYZ.Z.SUBSTITUTION.11.12.111.99.ASDDL"
我有以下代码
"ABC.A.SVN.10.10.390.10.UDGGL"
"XYZ.Z.SVN.11.12.111.99.ASDDL"
我需要替换第二个和第三个点之间的字符。在这种情况下它是 SVN
但它很可能是 A
和 ZZZ
之间的任意组合,因此真正实现此目的的唯一方法是使用点。
要求的结果是:
"ABC.A..10.10.390.10.UDGGL"
"XYZ.Z..11.12.111.99.ASDDL"
我尝试了 grep("^.+(\.\).$", "ABC.A.SVN.10.10.390.10.UDGGL")
的变体,但出现错误。
一些我尝试过但没有成功的例子:
Link 1 Link 2
编辑
我尝试了@Onyambu 的第一种方法,然后 运行 变成了一个我没有考虑过的变体:"ABC.A.AB11.1.12.112.1123.UDGGL"
。在替换部分,我也有数值。期望的结果是 "ABC.A..1.12.112.1123.UDGGL"
我在他回答的第二部分使用 sub("\.\w+.\B.",".",x)
得到它!
x= "ABC.A.SVN.10.10.390.10.UDGGL" "XYZ.Z.SVN.11.12.111.99.ASDDL"
sub("([A-Z]+)(\.\d+)","\2",x)
[1] "ABC.A..10.10.390.10.UDGGL" "XYZ.Z..11.12.111.99.ASDDL"
([A-Z]+)
捕获任何包含字符 A-Z 的单词(\.\d+)
上面捕获的单词必须跟一个点,即\.
。这个点后面跟着数字,即\d+
。这样就完成了捕获。
到目前为止,字符串 "ABC.A.SVN.10.10.390.10.UDGGL"
的捕获部分是 SVN.10
,因为这是匹配正则表达式的部分。但是这部分被捕获为SVN
和.10
。我们做一个反向引用,即将整个 SVN.10
替换为第二部分 .10
另一个可行的逻辑:
sub("\.\w+.\B.",".",x)
[1] "ABC.A..10.10.390.10.UDGGL" "XYZ.Z..11.12.111.99.ASDDL"
x <- c("ABC.A.SVN.10.10.390.10.UDGGL", "XYZ.Z.SVN.11.12.111.99.ASDDL")
sub("^(?:[^.]*\.){2}\K[^.]*", "", x, perl=T)
^
在行首声明位置(?:[^.]*\.){2}
恰好匹配以下两次[^.]*\.
匹配除.
以外的任何字符任意次数,后跟.
\K
重置模式的起点。任何先前消耗的字符不再包含在最终匹配中[^.]*
匹配除.
之外的任何字符任意次数
结果 [1] "ABC.A..10.10.390.10.UDGGL" "XYZ.Z..11.12.111.99.ASDDL"
不完全是正则表达式,但这是另一种方法
#DATA
S = c("ABC.A.SVN.10.10.390.10.UDGGL", "XYZ.Z.SVN.11.12.111.99.ASDDL")
sapply(X = S,
FUN = function(str){
ind = unlist(gregexpr("\.", str))[2:3]
paste(c(substring(str, 1, ind[1]),
"SUBSTITUTION",
substring(str, ind[2], )), collapse = "")
},
USE.NAMES = FALSE)
#[1] "ABC.A.SUBSTITUTION.10.10.390.10.UDGGL" "XYZ.Z.SUBSTITUTION.11.12.111.99.ASDDL"