【发布时间】:2013-09-03 08:23:34
【问题描述】:
string<-c(" this is a string ")
是否可以在字符串的两侧(或根据需要仅在一侧)修剪掉空格并将其替换为所需的字符,例如 R 中的这个?字符串两边的空格数不同,替换时必须保留。
"~~~~~~~this is a string~~"
【问题讨论】:
string<-c(" this is a string ")
是否可以在字符串的两侧(或根据需要仅在一侧)修剪掉空格并将其替换为所需的字符,例如 R 中的这个?字符串两边的空格数不同,替换时必须保留。
"~~~~~~~this is a string~~"
【问题讨论】:
这似乎是一种低效的方法,但也许你应该关注gregexpr 和regmatches 而不是gsub:
x <- " this is a string "
pattern <- "^ +?\\b|\\b? +$"
startstop <- gsub(" ", "~", regmatches(x, gregexpr(pattern, x))[[1]])
text <- paste(regmatches(x, gregexpr(pattern, x), invert=TRUE)[[1]], collapse="")
paste0(startstop[1], text, startstop[2])
# [1] "~~~~this is a string~~"
而且,为了好玩,作为一个函数,以及一个“矢量化”函数:
## The function
replaceEnds <- function(string) {
pattern <- "^ +?\\b|\\b? +$"
startstop <- gsub(" ", "~", regmatches(string, gregexpr(pattern, string))[[1]])
text <- paste(regmatches(string, gregexpr(pattern, string), invert = TRUE)[[1]],
collapse = "")
paste0(startstop[1], text, startstop[2])
}
## use Vectorize here if you want to apply over a vector
vReplaceEnds <- Vectorize(replaceEnds)
一些样本数据:
myStrings <- c(" Four at the start, 2 at the end ",
" three at the start, one at the end ")
vReplaceEnds(myStrings)
# Four at the start, 2 at the end three at the start, one at the end
# "~~~~Four at the start, 2 at the end~~" "~~~three at the start, one at the end~"
【讨论】:
gsub 是矢量化了吗?
使用gsub:
gsub(" ", "~", " this is a string ")
[1] "~~~~this~is~a~string~~"
此函数使用正则表达式替换(即 sub)字符串中所有出现的模式。
在你的情况下,你必须用一种特殊的方式来表达模式:
gsub("(^ *)|( *$)", "~~~", " this is a string ")
[1] "~~~this is a string~~~"
图案的意思:
(^ *):在字符串的开始处找到一个或多个空格( *$):在字符串的结尾找到一个或多个空格`|: OR 运算符现在您可以使用这种方法来解决用新字符替换每个空格的问题:
txt <- " this is a string "
foo <- function(x, new="~"){
lead <- gsub("(^ *).*", "\\1", x)
last <- gsub(".*?( *$)", "\\1", x)
mid <- gsub("(^ *)|( *$)", "", x)
paste0(
gsub(" ", new, lead),
mid,
gsub(" ", new, last)
)
}
> foo(" this is a string ")
[1] "~~~~this is a string~~"
> foo(" And another one ")
[1] "~And another one~~~~~~~~"
如需了解更多信息,请参阅?gsub 或?regexp。
【讨论】:
或者使用更复杂的模式匹配和gsub...
gsub("\\s(?!\\b)|(?<=\\s)\\s(?=\\b)", "~", " this is a string " , perl = TRUE )
#[1] "~~~~this is a string~~"
或者用@AnandaMahto 的数据:
gsub("\\s(?!\\b)|(?<=\\s)\\s(?=\\b)", "~", myStrings , perl = TRUE )
#[1] "~~~~Four at the start, 2 at the end~~"
#[2] "~~~three at the start, one at the end~"
这使用了正负前瞻和后瞻断言:
\\s(?!\\b) - 匹配一个空格,\\s 后面没有单词边界,(?!\\b)。这对于除了第一个单词之前的最后一个空格之外的所有内容都可以单独工作,即我们自己会得到"~~~~ this is a string~~"。所以我们需要另一种模式......
(?<=\\s)\\s(?=\\b) - 匹配一个空格,\\s, 前面是另一个空格,(?<=\\s) 和 后跟一个单词边界,@ 987654331@.
它是gsub,所以它会尝试尽可能多地进行匹配。
【讨论】: