我有一个字符向量,其中一些条目最后有一定的模式。我想从最后删除这个模式并把它放在其余的前面。
示例:
#My initial character vector
names <- c("sdadohf abc", "fsdgodhgf abc", "afhk xyz")
> names
[1] "sdadohf abc" "fsdgodhgf abc" "afhk xyz"
#What I want is to move "abc" to the front
> names
[1] "abc sdadohf" "abc fsdgodhgf" "afhk xyz"
有没有简单的方法来实现这一点,还是我必须编写自己的功能?
答案 0 :(得分:3)
首先让我们在你的向量中添加一个字符串,一个在文本之间有多个空格。
names <- c("sdadohf abc", "fsdgodhgf abc", "afhk xyz", "aksle abc")
您可以在sub()
中使用捕获组。
sub("(.*?)\\s+(abc)$", "\\2 \\1", names)
# [1] "abc sdadohf" "abc fsdgodhgf" "afhk xyz" "abc aksle"
正则表达式解释由regex101提供:
(.*)
第一个捕获组 - 在零和无限次之间匹配任何字符(换行符除外),尽可能少,根据需要进行扩展\\s+
在一次和无限次之间匹配任何空格字符[\r\n\t\f ]
,尽可能多次,根据需要返回(abc)
第二个捕获组 - abc
按字面匹配字符abc
,$
断言字符串末尾的位置当我们在"\\2 \\1"
中交换组时,我们将第二个捕获组abc
带到字符串的开头。
感谢@Jota和@docendodiscimus帮助改进我原来的正则表达式。
答案 1 :(得分:1)
使用此
sub("(.*) \\b(abc)$", "\\2 \\1", names)
.*
是一场贪婪的比赛。在找到以abc
结尾的字符串之前,它将尽可能多地匹配。
.*
位于首次捕获的群组(\\1)
abc
位于第二个被捕获的群组(\\2)
我们可以使用\\2 \\1
来交换他们的位置,以找到我们的结果字符串
答案 2 :(得分:1)
这是一种拆分方法。我们将“名称”拆分为一个或多个空格(\\s+
),然后是“abc”((?=abc)
),使用list
循环遍历vapply
,反转({{ 1}})rev
元素和list
它们在一起。
paste
vapply(strsplit(names, "\\s+(?=abc)", perl=TRUE), function(x)
paste(rev(x), collapse=" "), character(1))
#[1] "abc sdadohf" "abc fsdgodhgf" "afhk xyz" "abc aksle"