简体   繁体   中英

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

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

Input: s = 'HelloWorld-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, ie 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 (ie 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

References

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM