2010-02-28 34 views
14

Đây là một chức năng tôi đã viết để phá vỡ một chuỗi dài vào dòng không dài hơn chiều dài choChèn ngắt dòng trong dài chuỗi - từ quấn

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

Nó hoạt động cho vấn đề tôi đã; nhưng tôi tự hỏi liệu tôi có thể học được điều gì đó ở đây không. Có một giải pháp ngắn hơn hoặc hiệu quả hơn, đặc biệt là tôi có thể loại bỏ vòng lặp for?

Trả lời

35

Làm thế nào về điều này:

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

Nó sẽ phá vỡ chuỗi "s" vào dòng với tối đa 90 ký tự (không bao gồm các nhân vật ngắt dòng "\ n", nhưng trong đó có không gian liên từ), trừ trường hợp có một từ chính nó vượt quá 90 ký tự, sau đó chính từ đó sẽ chiếm toàn bộ một dòng.

Bằng cách này, chức năng của bạn dường như bị phá vỡ --- bạn nên thay thế

lineLen <- 0 

với

lineLen <- wordLen[i] 
+0

Giải pháp tuyệt vời! Tôi cảm thấy tôi cần phải tìm hiểu về các biểu thức chính quy, Cảm ơn bạn đã chỉ ra sai lầm trong chức năng của tôi. –

+0

Bạn có thể thêm ghi chú giải thích từng phần cụ thể không? – theforestecologist

3

Bạn có thể nhìn vào ví dụ write.dcf() CHỨC NĂNG trong bản thân R; nó cũng sử dụng một vòng lặp để không có gì phải xấu hổ ở đây.

Mục tiêu đầu tiên là làm cho nó đúng --- xem Chambers (2008).

+2

Kiểm tra write.dcf (và sau đó formatDL) đưa ra hàm strwrap thực hiện chính xác những gì hàm của tôi cố gắng thực hiện. –

+0

Hoàn hảo - Tôi biết có điều gì đó nhưng tôi đã không ngay lập tức tìm thấy nó. Tôi cần điều này một lần cho CRANberries ... –

15

Vì lợi ích của sự hoàn chỉnh, Karsten W. điểm bình luận tại strwrap, đó là chức năng đơn giản nhất cần nhớ:

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

và để phù hợp chính xác các giải pháp được đề xuất trong câu hỏi, chuỗi phải được dán sau đó:

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

Bài đăng này được cố tình tạo thành cộng đồng wiki vì vinh dự tìm thấy hàm không phải của tôi.

+0

Nếu bạn cần điều này như một hàm, bạn cũng có thể sửa đổi 'strwrap' trong' sapply' cho công thức do người dùng định nghĩa sau: 'trimmer <- function (x, break_limit) { sapply (strwrap (x, break_limit, simplify = FALSE), dán, thu gọn = "\ n") } ' –

6

Để hoàn chỉnh hơn nữa, có:

  • stringi::stri_wrap
  • stringr::str_wrap (mà chỉ cuối cùng gọi stringi::stri_wrap

Phiên bản stringi sẽ đối phó với các bộ ký tự tốt hơn (nó được xây dựng trên thư viện ICU) và trong C/C++, nó sẽ nhanh hơn base::strwrap. Nó cũng được vector hóa trên tham số str.

Các vấn đề liên quan