2016-04-29 10 views
5

まで、後続の文字で埋めます。マッチ大文字と私は、たとえば、キャメルケースの文字列を持っている特定の文字列の長さ

私はこれらの規則に従うことで長さ4の文字列を形成したいと思います:

  • すべて大文字をつかみます。
  • は、4つの以上の大文字場合は、最初の4保ちます。

    • 4未満の大文字の場合、長さはここ4

    なるまで、最後大文字に続く文字を大文字にし、追加が発生する可能性があり3例がありますThisIsMyStringTIMS(大文字)をもたらします。

  • ThisIsOneVeryLongString
  • TIOV(第4大文字)をもたらします。
  • MyStringは、MSTR(大文字trが大文字)となります。

私はこのスニペットと最初の2例を解決するために管理:

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

はしかし、私はどのように私は最高のも最後のケースを扱う(あるいはしようとするために、上記のスニペットを変更することができ、非常にわかりません何か違います)。

P .:文字列は、少なくとも大文字と4文字を持つことが保証されています。しかし、理論的に資本がない場合は、最初の4文字を考慮する必要があります。 4文字がない場合、欠けている文字は最初のアルファベット文字(abcd)で埋められることがあります。しかし、前述したように、これら2つのエッジケースは通常は起こりません。ここで

答えて

4

は、最初の4つの文字とUPCASEをつかむ、その後、何も資本の前に任意の文字(複数可)を交換してください:

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

これは何のCAPIを処理していませんタルも。余分な文字のエッジケースについては、 "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

面白そうです。 1つの正規表現を使用する方法はありますか?私はどのように "すべての出現が、最後の1つの"正規表現を書くことができるか分からない。 – linkyndy

+0

大文字の不明確な数を単一の正規表現で小文字で区切ってマッチさせることはできますが、大文字だけをキャプチャする方法はありません。 –

1

は2つの方法です。String#upcase続い

#1正規表現で使用String#gsub、そしてString#[]

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を返したい場合0文字の場合は、そのチェックをメソッドに追加します。

関連する問題