2016-04-29 14 views
5

我有一個駱駝字符串,例如:JustAString匹配大寫字母,並填入隨後的字母,直到某些字符串的長度爲

我想通過以下規則來形成長度爲4的字符串:

  • 抓住所有大寫字母;
  • 如果超過4個大寫字母,只保留前4個;
  • 如果少於4個大寫字母,大寫,並添加下面的最後大寫字母,直到長度變爲4

這裏有3例可能發生:

  • ThisIsMyString將產生TIMS(首都);
  • ThisIsOneVeryLongString將產生TIOV(前4個首都);
  • MyString將產生MSTR(首都+ tr大寫)。

我設法解決在前兩種情況下在這個片段:

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

不過,我不太確定我如何才能最好地修改上面的代碼中也處理最後的情況下(甚至嘗試有些不同)。

P.S .:字符串保證至少有一個大寫字母和4個字符。但是,如果理論上缺少資本,則應考慮前4個字符。如果沒有4個字符,則缺少的字符可能會填入第一個字母字符(abcd)。但是,如前所述,這兩種邊緣情況通常不會發生。

回答

4

更換任何字符(s)表示,之前有沒有什麼資本,然後抓住前4個字符和upcase :

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

這種處理不CAPI tals也是。至於沒有足夠字符的邊緣情況,您可以追加「abcd」,但我會發現它更簡潔,只需在事實之後單獨執行此操作:output_string = (output_string + "abcd")[0..3] if output_string.length < 4。如果這確實是一種罕見的邊緣情況,這會讀得更乾淨並且表現得更好(不合理)。

+1

不錯的,安德魯。你也可以寫'str.gsub(/ [^ A-Z] +([A-Z])/,'\ 1')[0,4] .upcase'。 –

+0

這確實很整齊!謝謝! – linkyndy

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 
+0

它看起來很有趣。有沒有辦法使用一個正則表達式?我不知道你如何寫一個「所有事件,但最後一個」正則表達式。 – linkyndy

+0

您可以在一個正則表達式中匹配未知數量的大寫字母,可能由小寫字母分隔,但無法僅捕獲大寫字母。 –

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個字符,將該檢查添加到方法中。

相關問題