我正在尝试将所有出现的特定模式移到字符串的开头。例如,如果模式为'pat',那么我想用正则表达式替换来转换
'a pat b pat c pat d'
到
'pat pat a b c d'
我可以通过重复应用
来实现string <- gsub(x=string,pattern='(.*)(pat )(.*)',replacement='\\2\\1\\3')
到我的初始字符串值,但这需要在字符串上循环任意次,因为我不知道期望模式在字符串中出现多少次。我也不能简单地采用贪婪的方法,例如应用替换次数与字符串的长度一样多,因为我正在处理长度可变的字符串的极长向量并应用向量替换。
那么,有没有办法通过单个正则表达式来实现此功能?
编辑
共识似乎是不能使用单个regex / gsub表达式来完成。我应该提供更多详细信息,说明当其他解决方案只能在更严格的情况下使用时,为什么这正是我所需要的:
我正在处理一个大型数据集(数百万行),该数据集包含一个希望在其上执行清理规则的字符串字段。这些规则由一个单独文件中指定的正则表达式替换列表组成;有几百个。通过遍历正则表达式规则并通过gsub
的矢量化版本将每个规则应用于整个字符串列来进行清理过程。
对于某些规则(不是全部),我想确定特定模式的所有实例,然后将所有此类实例移到字符串的开头。指定的模式将从一条规则更改为另一条规则,因此没有任何方法可以利用寻求的模式的细节。
除非对流程进行一些认真的重组,否则我似乎无法实现自己的目标,除非有人有任何聪明的主意...
答案 0 :(得分:1)
您可以尝试以下一些非常幼稚的操作:
s <- 'a pat b pat c pat d'
s <- unlist(strsplit(s, " "))
stringtomatch <- "pat"
paste(c(s[grepl(stringtomatch, s)], s[!grepl(stringtomatch, s)]), collapse = " ")
[1] "pat pat pat a b c d"
或查看regex
以了解高级用例
答案 1 :(得分:1)
假设模式是固定的字符串(在问题的示例中就是这种情况),计算模式发生的次数,并使用strrep
创建模式的许多重复,然后将其重复到没有模式的原始字符串:
pat <- "pat"
pats <- paste0(" *", pat, " *")
paste0(strrep(paste0(pat, " "), lengths(gregexpr(pats, x))), gsub(pats, " ", x))
## [1] "pat pat pat a b c d" "pat pat pat a b c d"
如果该模式不是固定字符串,则将其提取并粘贴到没有它的原始字符串之前。
library(gsubfn)
paste(sapply(strapply(x, pat), paste, collapse = " "), gsub(pats, " ", x))
## [1] "pat pat pat a b c d" "pat pat pat a b c d"
输入数据是一个字符向量:
x <- 'a pat b pat c pat d'
x <- c(x, x)
答案 2 :(得分:0)
这不是单个正则表达式扩展,但是您也可以尝试stringr
包,因为stringr
pacakge下的函数是在string
和pattern
上向量化的。
library(stringr)
my_str <- 'a pat b pat c pat d'
my_pat <- c("pat")
# Capture the sepcified pattern
s1 <- unlist(lapply(str_extract_all(my_str, my_pat), FUN = function(x) paste(x, collapse = " ")))
# Remove the captured patterns from the string
s2 <- str_remove_all(my_str, my_pat)
# Move the first pattern to the beginning
str_c(s1, s2, sep = " ")
[1] "pat pat pat a b c d"
仍然适用于字符串和模式向量:
library(stringr)
my_str <- c('a pat b pat c pat d', 'x pet y pet zz pet')
my_pat <- c("pat", 'pet')
# Capture the sepcified pattern
s1 <- unlist(lapply(str_extract_all(my_str, my_pat), FUN = function(x) paste(x, collapse = " ")))
# Remove the captured patterns from the string
s2 <- str_remove_all(my_str, my_pat)
# Move the first pattern to the beginning
str_c(s1, s2, sep = " ")
[1] "pat pat pat a b c d" "pet pet pet x y zz "