该stringr包有乐于助人str_replace()和str_replace_all()功能。例如
mystring <- "one fish two fish red fish blue fish"
str_replace(mystring, "fish", "dog") # replaces the first occurrence
str_replace_all(mystring, "fish", "dog") # replaces all occurrences
Run Code Online (Sandbox Code Playgroud)
太棒了 但是你怎么样
有用的答案在很大程度上取决于字符串以及您对它的了解。使用正则表达式,一种选择是构建一个匹配整行但在不同部分的正则表达式,这样您就可以将您喜欢的部分放回:
str_replace(mystring, '(^.*?fish.*?)(fish)(.*?fish.*)', '\\1dog\\3')
# [1] "one fish two dog red fish blue fish"
Run Code Online (Sandbox Code Playgroud)
其中替换中的\\1和分别匹配捕获的第一个和第三个括号。\\3请注意惰性(不贪婪)量词*?,它们很重要,因此您不会过度匹配。
当然,您可以执行相同的操作来匹配第三次或第四次出现:
str_replace(mystring, '(^.*?fish.*?fish.*?)(fish)(.*)', '\\1dog\\3')
# [1] "one fish two fish red dog blue fish"
str_replace(mystring, '(^.*?fish.*?fish.*?fish.*?)(fish)(.*?)', '\\1dog\\3')
# [1] "one fish two fish red fish blue dog"
Run Code Online (Sandbox Code Playgroud)
但这并不是非常有效。您可以使用量词来重复,但它们会使替换组的编号有点混乱:
str_replace(mystring, '^((.*?fish.*?){3})(fish)(.*?)', '\\1dog\\4')
# [1] "one fish two fish red fish blue dog"
Run Code Online (Sandbox Code Playgroud)
但如果您将重复组设置为非捕获(?: ... ),则更有意义:
str_replace(mystring, '^((?:.*?fish.*?){3})(fish)(.*?)', '\\1dog\\3')
# [1] "one fish two fish red fish blue dog"
Run Code Online (Sandbox Code Playgroud)
不过,所有这些都是大量的正则表达式。一个更简单的选项(我想,取决于上下文以及您对正则表达式的喜欢程度)可能是使用strsplit然后重新组合,collapse分别:
mystrlist <- strsplit(mystring, 'fish ')[[1]] # match the space so not the last "fish$"
paste0(c(mystrlist[1],
paste0(mystrlist[2:3], collapse = 'dog '),
mystrlist[4]),
collapse = 'fish ')
# [1] "one fish two dog red fish blue fish"
paste0(c(mystrlist[1:2],
paste0(mystrlist[3:4], collapse = 'dog ')),
collapse = 'fish ')
# [1] "one fish two fish red dog blue fish"
Run Code Online (Sandbox Code Playgroud)
当然,这对于最后一个单词来说效果不太好,但是行尾正则表达式标记$使得使用str_replace(或只是sub)非常容易达到此目的:
sub('fish$', 'dog', mystring)
# [1] "one fish two fish red fish blue dog"
Run Code Online (Sandbox Code Playgroud)
底线:这在很大程度上取决于上下文,最佳选择是什么,但遗憾的是,没有额外的参数来替换哪个匹配。
| 归档时间: |
|
| 查看次数: |
633 次 |
| 最近记录: |