在字符限制处拆分文本并返回字符串数组

时间:2011-06-30 18:52:25

标签: ruby algorithm

使用我的cpp技巧,我开发了以下旧式递归方法,将文本拆分为字符串数组,最接近字数中断或由字符数参数限制(“限制”):

#see below for sample usage 
def split_at_limit(text, limit, result)
  slices = text.scan(/.{1,#{limit}}/m)
  return if slices.blank?
  first_slice = slices.first
  if first_slice.last == " " || (slices.length > 1 && slices[1].first == " ")
    result << first_slice
    slices.delete_at 0
    split_at_limit(slices.join, limit, result)
  elsif slices.length > 1
    first_slice_length = first_slice.length - 1
    appendix = ""
    i = 0
    first_slice_length.times do |i|
      break if first_slice[first_slice_length-i].chr == " "
      appendix = "#{first_slice[first_slice_length-i].chr}#{appendix}"
      first_slice[first_slice_length-i] = ''
    end
    first_slice = slices.first if i == first_slice.length
    result << first_slice
    slices.delete_at 0
    slices[0] = "#{appendix}#{slices[0]}"
    split_at_limit(slices.join, limit, result)
  end
  result
end

它服务于目的,但是有更好的方法(快速算法)来实现上述目标吗?

修改

样本用法

def datadump
return <<-END_TEXT
Suspendisse ut neque magna, nec elementum odio. Integer quis massa tortor, commodo tincidunt augue. Donec congue lacinia odio in aliquet. Ut vehicula elementum mi id lobortis. Sed eget pretium orci. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vel velit hendrerit nisl facilisis gravida quis ac nunc. Morbi tincidunt ligula ut turpis faucibus placerat. Duis commodo turpis vehicula diam imperdiet eu sollicitudin erat luctus. Nulla facilisi. Aenean aliquam facilisis enim et ultrices. Nulla adipiscing semper massa quis egestas. Nam tempus suscipit semper. Suspendisse sed venenatis lacus.

  Phasellus ac tortor a nisi porttitor rutrum eu nec odio. Cras pulvinar, eros non faucibus semper, odio odio mollis justo, vulputate rhoncus odio justo id purus. Donec tincidunt malesuada enim, luctus tempor augue interdum id. Maecenas luctus imperdiet justo, ut vulputate turpis varius et. Nunc placerat pellentesque interdum. Pellentesque porta dignissim neque a dignissim. Mauris vitae nisi at tortor hendrerit accumsan in at est. Phasellus erat mi, eleifend eu imperdiet sit amet, accumsan posuere risus. Donec at faucibus libero. Proin lectus risus, aliquet a dictum nec, iaculis a diam. Ut velit nibh, ultricies eget convallis a, dignissim vitae tortor. Fusce sed lorem mauris, non gravida nisi.

  Aliquam malesuada cursus dui, in vestibulum lectus vulputate ut. Proin semper facilisis augue, ut imperdiet erat facilisis ac. Maecenas laoreet faucibus mi, ut mollis diam aliquet scelerisque. Praesent sit amet magna quam, nec auctor nisi. Cras tristique varius scelerisque. Donec vehicula lectus ac urna fermentum faucibus. Aenean nec augue vitae dui tristique luctus. Donec lacus leo, pellentesque ut aliquet vitae, eleifend bibendum neque. Vivamus id diam risus, et ornare magna. Praesent quam dui, congue ut cursus sed, egestas id tortor. Integer eget lacus purus. Sed fermentum convallis quam, sit amet dapibus mi tristique non. Donec vehicula ligula eget risus varius aliquam. Praesent ut odio eu sem mollis euismod. Donec egestas tincidunt dolor et imperdiet. 
 END_TEXT
end

puts split_at_limit(datadump, 40, []).inspect

#gives=>["Suspendisse ut neque magna, nec ", "elementum odio. Integer quis massa ", "tortor, commodo tincidunt augue. Donec ", "congue lacinia odio in aliquet. Ut ", "vehicula elementum mi id lobortis. Sed ", "eget pretium orci. Cum sociis natoque ", "penatibus et magnis dis parturient ", "montes, nascetur ridiculus mus. Nulla ", "vel velit hendrerit nisl facilisis ", "gravida quis ac nunc. Morbi tincidunt ", "ligula ut turpis faucibus placerat. Duis", " commodo turpis vehicula diam imperdiet ", "eu sollicitudin erat luctus. Nulla ", "facilisi. Aenean aliquam facilisis enim ", "et ultrices. Nulla adipiscing semper ", "massa quis egestas. Nam tempus suscipit ", "semper. Suspendisse sed venenatis ", "lacus.\n\n      Phasellus ac tortor a nisi", " porttitor rutrum eu nec odio. Cras ", "pulvinar, eros non faucibus semper, odio", " odio mollis justo, vulputate rhoncus ", "odio justo id purus. Donec tincidunt ", "malesuada enim, luctus tempor augue ", "interdum id. Maecenas luctus imperdiet ", "justo, ut vulputate turpis varius et. ", "Nunc placerat pellentesque interdum. ", "Pellentesque porta dignissim neque a ", "dignissim. Mauris vitae nisi at tortor ", "hendrerit accumsan in at est. Phasellus ", "erat mi, eleifend eu imperdiet sit amet,", " accumsan posuere risus. Donec at ", "faucibus libero. Proin lectus risus, ", "aliquet a dictum nec, iaculis a diam. Ut", " velit nibh, ultricies eget convallis a,", " dignissim vitae tortor. Fusce sed lorem", " mauris, non gravida nisi.\n\n      ", "Aliquam malesuada cursus dui, in ", "vestibulum lectus vulputate ut. Proin ", "semper facilisis augue, ut imperdiet ", "erat facilisis ac. Maecenas laoreet ", "faucibus mi, ut mollis diam aliquet ", "scelerisque. Praesent sit amet magna ", "quam, nec auctor nisi. Cras tristique ", "varius scelerisque. Donec vehicula ", "lectus ac urna fermentum faucibus. ", "Aenean nec augue vitae dui tristique ", "luctus. Donec lacus leo, pellentesque ut", " aliquet vitae, eleifend bibendum neque.", " Vivamus id diam risus, et ornare magna.", " Praesent quam dui, congue ut cursus ", "sed, egestas id tortor. Integer eget ", "lacus purus. Sed fermentum convallis ", "quam, sit amet dapibus mi tristique non.", " Donec vehicula ligula eget risus varius", " aliquam. Praesent ut odio eu sem mollis", " euismod. Donec egestas tincidunt dolor "]

2 个答案:

答案 0 :(得分:2)

假设:

  

您希望将文本拆分为每个最多40个字符的长字符串。并且每个字符串在一个尽可能接近极限的字边界(即40)处被分割,但不应超过限制。

这是一个解决方案:

def datadump
  return <<-END_TEXT
Suspendisse ut neque magna, nec elementum odio. Integer quis massa tortor, commodo tincidunt augue. Donec congue lacinia odio$
  END_TEXT
end

a = datadump.split(/(.{1,40}\b)/)
a = a.reject{|el| el.size == 0}
puts a # or p a  to see results

答案 1 :(得分:0)

您正在寻找自动换行算法。

显示了here的解决方案。

正则表达式的全面解释是there

来自Ruby On Rails的

word_wrap实现。