我想用新文本替换第一个和第二个句点之间的数字。
old <- c("test_test.123.test.test", "something.456.something")
例如,假设我希望old
成为:
"test_test.000.test.test" "something.111.something"
我正在尝试学习如何模式化。我认为它可能是这样的:
grep("^[:punct:][[:digit:]]+[:punct:]$", old)
......但没有运气。一旦我开始工作,我可以在key
:
key <- data.frame(old=c("123", "456"),
new=c("000", "111"))
更新:我采用了@ fishtank的基本想法并对其进行了修改以适应我更复杂的用例。我的原始示例具有相同长度的向量,但我的实际案例在key
和old
之间存在一对多的关系。这个循环适合我。
old <- c("test_test.123.test.test", "something.456.something",
"repeat.456.something")
key <- data.frame(old=c("123", "456"),
new=c("000", "111"))
for (i in old) {
o <- substr(gsub("^[^.]*.", "", i), 1, 3)
n <- key[key$old==o,]$new
r <- gsub(o, n, i)
print(r)
}
#[1] "test_test.000.test.test"
#[1] "something.111.something"
#[1] "repeat.111.something"
答案 0 :(得分:4)
您可以mapply
使用gsub
替换key
。如果你的字符串更复杂,你可能想在gsub
中尝试不同的正则表达式。
> key
old new
1 123 000
2 456 111
> old
[1] "test_test.123.test.test" "something.456.something"
> cbind(old,new=mapply(gsub,key$old,key$new,old))
old new
[1,] "test_test.123.test.test" "test_test.000.test.test"
[2,] "something.456.something" "something.111.something"
答案 1 :(得分:1)
我怀疑我的正则表达式可以改进,但我认为这应该有效
library(stringr)
str_replace_all(old, "\\b[[:digit:]]+\\b", c("000", "111"))
一个纯正的正则表达式,但相当丑陋与R
中所需的所有转义str_replace_all(old, "\\(?<=\\.\\)\\d+\\(?=\\.\\)", c("000", "111"))
答案 2 :(得分:0)
正确的模式应为"[[:punct:]][[:digit:]]+[[:punct:]]"
,因为^
和$
将分别匹配每个元素的开头和结尾。这里你的两端都有其他角色。
如果您想使用"\\.[[:digit:]]+\\."
逗号而不是任何标点符号,也可以使用grep
。
http://regexr.com/是一个很好的资源,可以轻松使用正则表达式。
答案 3 :(得分:0)
这会解决您的问题吗?
old <- c("test_test.123.test.test", "something.456.something")
key <- c("000", "111")
replace_key <- function(text, key) {
stringi::stri_replace_all_regex(text, "([:alpha:]+)\\.\\p{N}*\\.(.+)",
paste0("$1.", key, ".$2" ))
}
replace_key(old, key)
# [1] "test_test.000.test.test" "something.111.something"
确保安装stringi
。
关于正则表达式的简短说明:
([:alpha:]+)
匹配任何字母数字并将其保留为变量$1
\\.
逃脱了点\\p{N}*
匹配零个或多个Unicode字符类数字(.+)
匹配一个或多个字符,并将其保存在$2
paste
函数会添加您将来想要指定的密钥。