11

次のように、不足している文字をゼロで置き換えて、郵便番号を5桁の長さに正規化したいと思います。

"95616" >> "95616"
"854"  >> "00854"
"062" >> "00062"
"0016" >> "00016"

私は sprintf を sosprintf("%05s", zipcode)のように 使ってみましたsprintf("%0.5d", zipcode)。どちらも間違った答えを出します。の使用s:

"95616" >> "95616"
"854"   >> "  854"
"062"   >> "  062"
"0016"  >> " 0016"

これは正しい文字数ですが、ゼロではなくスペースを使用しています。

の使用d:

"95616" >> "95616"
"854"   >> "00854"
"062"   >> "00050"
"0016"  >> "00014"

この場合、sprintf() の適切な使用法は何ですか?

4

6 に答える 6

27

で自分を苦しめないでくださいsprintf

puts "123".rjust(5, '0') # => 00123
于 2012-12-28T23:51:35.610 に答える
8

sprintf の使い方は問題ありません。問題は、062 (および 0016) が 8 進数 (0 で始まる整数と同様) であり、base10 に変換すると 50 になることです。

解決策は、Ruby アプリにヒットする前にその 0 を取り除くことです。それが文字列であると仮定すると(あなたの例は文字列を示しているため)、次のようなことができます:

"062".gsub /^0/, ''

次に、パディングと印刷の書式設定を続けます。

もう 1 つの方法は、0 で始まることがわかっている場合は、8 進数として故意に出力することです。

"%05o" % 062 # => "00062"

もちろん、入力を制御できる場合は、予想外の数値を入力してコードを壊されないようにするのが最善の策です。例えば。

"%05s" % 0xff0055 # => 16711765
"%05x" % 0xff0055 # => "ff0055"

入力をチェックすると、問題が書式設定の問題から検証の問題に変わります。対処するよりも防止する方がよいでしょう。

(風変わりな % 構文はprintf/のシュガーですsprintf)

于 2012-12-28T23:58:56.463 に答える
6

%05d が必要です。また、ショートカットとして String#% :

"%05d" % "123" #=> 00123
于 2012-12-29T00:05:08.370 に答える
2

whirlwinの解決策は、有効な(一般的なパディング)解決策のようです。max で改善するだけです:

zipcode.insert 0, '0' * ([5 - zipcode.length, 0].max)

それを確認するには:

az = ["95616", "854", "062", "0016", '1', '123456']
az.collect {|zipcode| zipcode.insert 0, '0' * (5 - zipcode.length) }

$ ruby -w t.rb
t.rb:2:in `*': negative argument (ArgumentError)

負の値に対処するために max を追加します。

az = ["95616", "854", "062", "0016", '1', '123456']
az.collect {|zipcode| zipcode.insert 0, '0' * ([5 - zipcode.length, 0].max) }
p az

$ ruby -w t.rb
["95616", "00854", "00062", "00016", "00001", "123456"]
于 2012-12-29T09:58:58.683 に答える
0

皆様からのご意見ありがとうございました。私はsprintfについてもっと学び、特にソリューションでsprintfを使用することを探していましたが、すべてのアイデアが本当に役に立ちました。私は最終的に、柔軟性があり、まだ言及されていない私の問題に対する少しハッキーな解決策を見つけたので、それを投稿しようと思いました。

先に述べたようにsprintf("%05s", zipcode)、数値文字列が十分に長くない場合はゼロではなくスペースを返しますが、正しい数のスペースを返しましたgsub。そのため、スペースをゼロに置き換えるためにaを最後までチェーンしました。

sprintf("%05s", zipcode).gsub!(" ", "0")

このソリューションに重大な問題がある場合はお知らせください。私はそれをテストしました、そして今のところそれはうまくいくようです。

于 2012-12-29T10:05:56.120 に答える
0

このアプローチは実際には を使用しませんがsprintf、1 行のコードで問題を解決する必要があります。

zipcode.insert 0, '0' * (5 - zipcode.length)
于 2012-12-28T23:51:29.077 に答える