Show a string of certain length without truncating

五迷三道 提交于 2019-12-01 22:46:12

问题


I am displaying a string of certain length in ruby. only 80 characters of that string can be displayed in one line. for example if string length is 82 then it will be shown in 2 lines if length is 250 then string will be shown in 5 lines etc and i want to split on whitespace not the word.

I am new in this so don't know how can i solve this.


回答1:


def wrap(str, max_line_len)
  str.scan /(?<=\A| ).{1,#{max_line_len}}(?= |\z)/
end

str = "Little Miss Muffet she sat on her tuffet, eating her curds and whey. Along " + 
      "came a spider who sat down beside her and frightened Miss Muffet away."

         1         2         3    
123456789012345678901234567890123

puts wrap(str, 31)
Little Miss Muffet she sat on
her tuffet, eating her curds
and whey. Along came a spider
who sat down beside her and
frightened Miss Muffet away.

puts wrap(str, 32)
Little Miss Muffet she sat on
her tuffet, eating her curds and
whey. Along came a spider who
sat down beside her and
frightened Miss Muffet away.

puts wrap(str, 33)
Little Miss Muffet she sat on her
tuffet, eating her curds and
whey. Along came a spider who sat
down beside her and frightened
Miss Muffet away.

See String#scan. The regular expression reads, "match between 1 and max_line_len characters, immediately preceded by the beginning of the string or a space and immediately followed by a space or the end of the string". (?<=\A| ) is a positive lookbehind and (?= |\z) is a positive lookahead.




回答2:


Just out of curiosity:

loop.inject([[], input]) do |(acc, src)|
  if m = src[/.{1,79}(\s|\z)/]
    [acc << m, $']
  else
    break acc << src
  end
end



回答3:


A very quick and dirty, iterative version:

max_chars = 80
text = 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.'

lines = []
words = text.split

while words.length > 0
  line = words.shift

  while words.first && (line.length + words.first.length + 1) <= max_chars
    line << " #{words.shift}" 
  end

  lines << line
end

lines.each { |line|  puts line }
#=> Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod
#   tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At
#   vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren,
#   no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit
#   amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut
#   labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam
#   et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata
#   sanctus est Lorem ipsum dolor sit amet.



回答4:


Other option, not so clean, but...

The idea is to find the index of the spaces and substitute with \n the spaces at index close to the line length.

So, given the string str and the max_len:

delta = 0
(str + " ")
.each_char.with_index.with_object([]) { |(c, i), o| o << i if c == " "} # find the index of the spaces
.each_cons(2).with_object([]) do |(a, b), tmp| # select the index to be substituted
  if b > (tmp.size + 1) * max_len + delta
    tmp << a 
    delta = tmp.last - max_len * tmp.size + 1
  end
end.each { |i| str[i] = "\n" } # substitute

Now str has \n when line length is close to max_len. This alterates the original string.



来源:https://stackoverflow.com/questions/57440279/show-a-string-of-certain-length-without-truncating

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!