开发者

How to insert tag every 5 characters in a Ruby String?

开发者 https://www.devze.com 2023-01-06 14:49 出处:网络
I would like to insert a <wbr> tag every 5 characters. Input: s = \'Hel开发者_如何学编程loWorld-Hello guys\'

I would like to insert a <wbr> tag every 5 characters.

Input: s = 'Hel开发者_如何学编程loWorld-Hello guys'

Expected outcome: Hello<wbr>World<wbr>-Hell<wbr>o guys


s = 'HelloWorld-Hello guys'
s.scan(/.{5}|.+/).join("<wbr>")

Explanation:

Scan groups all matches of the regexp into an array. The .{5} matches any 5 characters. If there are characters left at the end of the string, they will be matched by the .+. Join the array with your string


There are several options to do this. If you just want to insert a delimiter string you can use scan followed by join as follows:

s = '12345678901234567'
puts s.scan(/.{1,5}/).join(":")
# 12345:67890:12345:67

.{1,5} matches between 1 and 5 of "any" character, but since it's greedy, it will take 5 if it can. The allowance for taking less is to accomodate the last match, where there may not be enough leftovers.

Another option is to use gsub, which allows for more flexible substitutions:

puts s.gsub(/.{1,5}/, '<\0>')
# <12345><67890><12345><67>

\0 is a backreference to what group 0 matched, i.e. the whole match. So substituting with <\0> effectively puts whatever the regex matched in literal brackets.

If whitespaces are not to be counted, then instead of ., you want to match \s*\S (i.e. a non whitespace, possibly preceded by whitespaces).

s = '123 4 567  890   1 2 3 456 7  '
puts s.gsub(/(\s*\S){1,5}/, '[\0]')
# [123 4 5][67  890][   1 2 3 45][6 7]  

Attachments

  • Source code and output on ideone.com

References

  • regular-expressions.info
    • Finite Repetition, Greediness
    • Character classes
    • Grouping and Backreferences
    • Dot Matches (Almost) Any Character


Here is a solution that is adapted from the answer to a recent question:

class String
  def in_groups_of(n, sep = ' ')
    chars.each_slice(n).map(&:join).join(sep)
  end
end

p 'HelloWorld-Hello guys'.in_groups_of(5,'<wbr>')
# "Hello<wbr>World<wbr>-Hell<wbr>o guy<wbr>s"

The result differs from your example in that the space counts as a character, leaving the final s in a group of its own. Was your example flawed, or do you mean to exclude spaces (whitespace in general?) from the character count?


To only count non-whitespace (“sticking” trailing whitespace to the last non-whitespace, leaving whitespace-only strings alone):

# count "hard coded" into regexp
s.scan(/(?:\s*\S(?:\s+\z)?){1,5}|\s+\z/).join('<wbr>')

# parametric count
s.scan(/\s*\S(?:\s+\z)?|\s+\z/).each_slice(5).map(&:join).join('<wbr>')
0

精彩评论

暂无评论...
验证码 换一张
取 消