2010-02-28 37 views
14

Aquí es una función que escribí para romper una larga cadena en líneas no más de una longitud dadaInsertar saltos de línea en cadena larga - Ajuste de línea

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) 
} 

Funciona para el problema que tuve; pero me pregunto si puedo aprender algo aquí. ¿Hay una solución más corta o más eficiente, especialmente puedo deshacerme del ciclo for?

Respuesta

35

¿Qué tal esto:

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

se romperá cadena "s" en líneas con un máximo de 90 caracteres (sin incluir el carácter de salto de línea "\ n", pero incluyendo los espacios entre palabras), a menos que haya una palabra en sí que supera los 90 caracteres, entonces esa palabra ocupará una línea completa.

Por cierto, su función parece roto --- se debe reemplazar

lineLen <- 0 

con

lineLen <- wordLen[i] 
+0

¡Gran solución! Siento que necesito aprender sobre expresiones regulares. Gracias por señalar el error en mi función también. –

+0

¿Podría agregar una nota explicando qué hace cada parte específicamente? – theforestecologist

3

Puedes ver, por ejemplo, la write.dcf() FUNCIÓN en R sí mismo; también usa un bucle, así que no hay nada de qué avergonzarse aquí.

El primer objetivo es hacerlo bien --- ver Chambers (2008).

+2

Inspeccionando write.dcf (y luego formatDL) aparece la función strwrap que hace exactamente lo que mi función intenta hacer. –

+0

Perfecto - Sabía que había algo, pero no lo encontré de inmediato. Lo necesitaba una vez para CRANberries también ... –

15

En aras de la exhaustividad, puntos de comentarios de Karsten W. en strwrap, que es la función más fácil de recordar:

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

y coinciden exactamente con la solución propuesta en la pregunta, la cadena tiene que puede pegar después:

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

Este post está hecho deliberadamente wiki de la comunidad ya que el honor de la búsqueda de la función no es la mía.

+0

Si necesita esto como una función, también puede modificar 'strwrap' en' sapply' para la siguiente fórmula definida por el usuario: 'trimmer <- function (x, break_limit) { sapply (strwrap (x, break_limit, simplify = FALSE), pegar, colapsar = "\ n") } ' –

6

Para la solicitud está completa, hay:

  • stringi::stri_wrap
  • stringr::str_wrap (que se pide solo en última instancia stringi::stri_wrap

La versión stringi se ocupará de los juegos de caracteres mejor (que está construido en la biblioteca de la UCI) y está en C/C++ por lo que finalmente será más rápido que base::strwrap. También se vectoriza sobre el parámetro str.