这是我写的一个函数,用于将长字符串分成不长于给定长度的行
strBreakInLines <- function(s, breakAt=90, prepend="") {
words <- unlist(strsplit(s, " "))
if (length(words)<2) return(s)
wordLen <- unlist(Map(nchar, words))
lineLen <- wordLen[1]
res <- words[1]
lineBreak <- paste("\n", prepend, sep="")
for (i in 2:length(words)) {
lineLen <- lineLen+wordLen[i]
if (lineLen < breakAt)
res <- paste(res, words[i], sep=" ")
else {
res <- paste(res, words[i], sep=lineBreak)
lineLen <- 0
}
}
return(res)
}
它适用于我遇到的问题;但我想知道我是否可以在这里学到一些东西。是否有更短或更有效的解决方案,尤其是我可以摆脱for循环?
答案 0 :(得分:44)
这个怎么样:
gsub('(.{1,90})(\\s|$)', '\\1\n', s)
它会将字符串“s”分成最多90个字符的行(不包括换行符“\ n”,但包括字间空格),除非有一个字本身超过90个字符,那么该字本身将会占据整条线。
顺便说一下,你的功能似乎已经破坏了 - 你应该替换
lineLen <- 0
与
lineLen <- wordLen[i]
答案 1 :(得分:22)
为了完整起见,Karsten W.的评论点在strwrap
,这是最容易记住的功能:
strwrap("Lorem ipsum... you know the routine", width=10)
并且要完全匹配问题中提出的解决方案,之后必须粘贴字符串:
paste(strwrap(s,90), collapse="\n")
这篇文章是故意制作社区维基的,因为找到该功能的荣誉不是我的。
答案 2 :(得分:13)
为了进一步完整,有:
stringi::stri_wrap
stringr::str_wrap
(最终会调用stringi::stri_wrap
stringi
版本将更好地处理字符集(它建立在ICU库上)并且它在C / C ++中,因此它最终会比base::strwrap
更快。它也在str
参数上进行了矢量化。
答案 3 :(得分:4)
你可以看看,例如R本身的write.dcf()
功能;它也使用循环,所以没有什么可以在这里感到羞耻。
第一个目标是让它正确 - 见Chambers(2008)。