Вставка разрывов строк в длинном переносе слов

Вот функция, которую я написал, чтобы сломать длинную строку в строки длиной не более заданной длины

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?

Ответы

Ответ 1

Как насчет этого:

gsub('(.{1,90})(\\s|$)', '\\1\n', s)

Он разбивает строку "s" на строки с максимум 90 символами (исключая символ разрыва строки "\n", но включая межсловные пространства), если только само слово не превышает 90 символов, тогда это слово будет занимают целую линию.

Кстати, ваша функция кажется сломанной - вы должны заменить

lineLen <- 0

с

lineLen <- wordLen[i]

Ответ 2

Для полноты, Karsten W. отмечает точки в strwrap, что является самой легкой функцией для запоминания:

strwrap("Lorem ipsum... you know the routine", width=10)

и чтобы точно соответствовать решению, предложенному в вопросе, строка должна быть вставлена ​​впоследствии:

paste(strwrap(s,90), collapse="\n")

Это сообщение намеренно создало сообщество wiki, поскольку честь найти функцию не принадлежит мне.

Ответ 3

Для дальнейшей полноты:

  • stringi::stri_wrap
  • stringr::str_wrap (который в конечном итоге вызывает stringi::stri_wrap

В версии stringi будет лучше использоваться набор символов (он построен на библиотеке ICU), а в C/С++ - в конечном итоге быстрее base::strwrap. Он также векторизован по параметру str.

Ответ 4

Вы можете посмотреть, например, ФУНКЦИЯ write.dcf() в самом R; он также использует петлю, поэтому нечего стыдиться здесь.

Первая цель - это правильно понять - см. Chambers (2008).