匹配大写字母并填写后续字母,直到某个字符串长度为

时间:2016-04-29 15:49:09

标签: ruby regex string

我有一个骆驼字符串,例如:JustAString

我想通过遵循以下规则来形成长度4 的字符串:

  • 抓住所有大写字母;
  • 如果超过4个大写字母,则只保留前4个;
  • 如果少于4个大写字母,请大写并添加 last 大写字母后面的字母,直到长度变为4。

以下是可能发生的3种情况:

  • ThisIsMyString将获得TIMS(首都);
  • ThisIsOneVeryLongString会产生TIOV(前4个大写字母);
  • MyString将获得MSTR(大写字母+ tr大写字母。)

我设法使用此代码段解决了前两个案例:

str.scan(/[A-Z]/).first(4).join

但是,我不太确定如何才能最好地修改上述代码片段来处理最后一个案例(甚至尝试不同的事情)。

P.S。:字符串保证至少有一个大写字母和4个字符。但是,如果理论上缺少资本,则应考虑前4个字符。如果没有4个字符,则可以使用第一个字母字符(abcd)填充缺少的字符。但是,如上所述,这两个边缘情况通常不会发生。

3 个答案:

答案 0 :(得分:4)

用任何东西替换任何在大写之前的字符,然后抓住前4个字符并大写:

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

这也不处理大写字母。至于没有足够的字符的边缘情况,你可以追加“abcd”,但我发现它只是在事后的单独行中更清晰:output_string = (output_string + "abcd")[0..3] if output_string.length < 4。如果这真的是一种罕见的边缘情况,那么读起来会更清晰并且表现得更好(无关紧要)。

答案 1 :(得分:3)

这是一个解决方案:

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

这里有评论:

(
  (
    str.scan(/[A-Z]/)[0..-2] + # All but the last capital letter
    str.scan(/[A-Z]?[^A-Z]*$/)  # 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

答案 2 :(得分:1)

以下是两种方法。

#1将String#gsub与正则表达式一起使用,然后使用String#upcaseString#[]

R = /
    [a-z]           # match a lower case letter
    (?=[a-z]*[A-Z]) # 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确定最后一个大写字母的索引,然后构建字符串

def get_caps(str, n)
  idx = str.rindex(/[A-Z]/)
  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"

如果您希望返回nil,如果返回的字符串包含少于n个字符,请将该检查添加到方法中。