Match the uppercase letters and fill them with subsequent letters up to a certain string length

I have a camel wrapper string, for example: JustAString .

I would like to create length 4 strings by following these rules:

  • capture all uppercase letters;
  • if more than 4 uppercase letters, save only the first 4;
  • if less than 4 uppercase letters, write down and add the letters that follow the last uppercase letter until the length becomes 4.

Here are three cases that can occur:

  • ThisIsMyString will give TIMS (capitals);
  • ThisIsOneVeryLongString will give a TIOV (first 4 capitals);
  • MyString will give MSTR (capitals + tr with a capital letter).

I managed to solve the first two cases using this snippet:

 str.scan(/[AZ]/).first(4).join 

However, I'm not quite sure how best to modify the above snippet to handle the last case (or even try something else).

PS: A string is guaranteed to have at least capital and 4 characters. However, if there is theoretically no capital, the first 4 characters should be considered. If 4 characters are not specified, spaces can be filled with the first characters of the alphabet ( abcd ). But, as already mentioned, these two extreme cases usually do not occur.

+5
source share
3 answers

Replace any character (s) that precedes capital with nothing, then take the first 4 characters and upper case:

str.gsub(/[^AZ]+([AZ])/){$1}[0..3].upcase

This also has no capital. As for the extreme case with insufficient characters, you can add "abcd", but I would find it cleaner to do it on a separate line after the fact: output_string = (output_string + "abcd")[0..3] if output_string.length < 4 . It reads a lot cleaner and performs (unwittingly) better if it is a truly rare edge case.

+4
source

Here's the solution:

 ((str.scan(/[AZ]/)[0..-2] + str.scan(/[AZ][^AZ]*$/)).join + "abcd")[0, 4].upcase 

And here he is with the comments:

 ( ( str.scan(/[AZ]/)[0..-2] + # All but the last capital letter str.scan(/[AZ]?[^AZ]*$/) # The last capital letter, if any, plus trailing lowercase letters ).join + "abcd" )[0, 4]. # Take the first 4 chars, 4 capitals if we have them, then trailing lowercase if we have those, then the "abcd" filler upcase # upcase any trailing lowercase letters we included 
+3
source

Here are two methods.

# 1 Use String # gsub with regex and then String # upcase and String # []

 R = / [az] # match a lower case letter (?=[az]*[AZ]) # match >= 0 lower case letters followed by an upper case letter # in a positive lookahead /x # free-spacing regex definition mode def get_caps(str, n) str.gsub(R,"").upcase[0,4] end get_caps("ThisIsMyString", 4) #=> "TIMS" get_caps("ThisIsOneVeryLongString", 4) #=> "TIOV" get_caps("MyString", 4) #=> "MSTR" get_caps("abcde", 4) #=> "ABCD" get_caps("", 4) #=> "" get_caps("AbcdefGh", 4) #=> "AGH" 

# 2 Determine the index of the last capital letter, and then build the line

 def get_caps(str, n) idx = str.rindex(/[AZ]/) return str[0,4].upcase if idx.nil? str.each_char.with_index.with_object('') { |(c,i),s| s << c.upcase if (s.size < n && (i > idx || c == c.upcase)) } end get_caps("ThisIsMyString", 4) #=> "TIMS" get_caps("ThisIsOneVeryLongString", 4) #=> "TIOV" get_caps("MyString", 4) #=> "MSTR" get_caps("abcde", 4) #=> "ABCD" get_caps("", 4) #=> "" get_caps("AbcdefGh", 4) #=> "AGH" 

If you want to return nil if the returned string contains fewer n characters, add this check to the methods.

+1
source

All Articles