2011-06-23 36 views
27

我需要一種格式數字的方法。我在我的數據庫表中存儲了一些數字,例如12500,並且希望以這種格式打印它們12 500(因此每3位數字有一個空格)。有沒有一個優雅的方式來做到這一點?如何將數字1000的格式設置爲「1 000」

+0

number_with_delimiter(12500,分隔符:「「) – nilid

回答

36

見:http://www.justskins.com/forums/format-number-with-comma-37369.html

沒有內置的方式(除非你使用Rails,的ActiveSupport是否有方法來做到這一點),但你可以使用正則表達式像

formatted_n = n.to_s.reverse.gsub(/...(?=.)/,'\&,').reverse 
+1

,將增加逗號,而不是空格順便說一句 – loosecannon

+5

只需用空格代替號(' \&,'用'\&'),它會起作用。 –

+1

謝謝你們的快速幫助。但是,說實話,我認爲這存在一些更好的方式(例如PHP中的[this function](http://php.net/manual/en/function.number-format.php))。但我怎麼說,感謝解決方案! – user1946705

3

所以,這是很瘋狂和hackish的,但它能夠完成任務......

12500.to_s.split("").reverse.each_slice(3).map {|y| y.join("").reverse}.reverse.join(" ") 
=> "12 500" 

.to_s: convert to string 
.split(""): split into separate digits 
.reverse: reverse order 
.each_slice(3): peel of each three digits (working from back end due to reverse) 
.map {|y| y.join("").reverse}: map into an array for each three digits - join back together with no delimiter and reverse order back to original 
.reverse: reverse order of mapped array 
.join(" "): join mapped array back together with space delimiter 
+0

這是聰明的使用'each_slice'來避免多餘的正則表達式 –

3

另一種方式:

12500.to_s.reverse().split(//).inject() {|x,i| (x.gsub(/ /,"").length % 3 == 0) ? x + " " + i : x + i}.reverse() 

您可以隨時打開類長整數,並添加此爲了方便:

module FormatNums 
    def spaceify 
    self.to_s.reverse().split(//).inject() {|x,i| (x.gsub(/ /,"").length % 3 == 0) ? x + " " + i : x + i}.reverse() 
    end 
end 

class Fixnum 
    include FormatNums 
end 

12500.spaceify # => "12 500" 
+0

哦,智者,是啊?非常好! +1 :) – Yardboy

+0

@Yardboy謝謝。使用Ruby,它不是內置的,因爲你可以很容易地在自己的內部構建它。對? – NullRef

+0

確實。爲了編碼而編碼,有什麼更好的? – Yardboy

19

的ActiveSupport使用這個正則表達式(並沒有反向反向)。

10000000.to_s.gsub(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1 ") #=> "10 000 000" 
+1

我會打開Integer類並添加一個方法。這抓住了Fixnum和Bignum。 –

+0

這很好。用/(\ d)(?=(\ d \ d \ d)+ $)/'來消除負面預測嗎? –

8

official document表明三種不同的方法:

1)使用回顧後和先行(需要oniguruma

12500.to_s.gsub(/(?<=\d)(?=(?:\d{3})+\z)/, ' ') 
# => "12 500" 

2)僅使用先行。與steenslag的答案完全相同。

3)使用既不超前,也不回顧後

s = 12500.to_s 
nil while s.sub!(/(.*\d)(\d{3})/, '\1 \2') 
s # => "12 500" 
+0

#3似乎依賴於貪婪。如果是這樣,我認爲如果使用'gsub!'或'sub!'就沒有關係。 'nil'可以被任何文字取代。正確?這總是等於'while s.gsub!(/(。* \ d)(\ d {3})/,'\ 1 \ 2'); (我認爲讀得更好一些)? –

+0

@CarySwoveland是的。 'gsub!'是不必要的。我編輯過。 – sawa

-2

我知道這是一個老問題,但。

爲什麼不只是使用子串替換。

在僞代碼

....

String numberAsString = convertNumberToString(123456); 
int numLength = V.length;//determine length of string 

String separatedWithSpaces = null; 

for(int i=1; i<=numlength; i++){//loop over the number 
separatedWithSpaces += numberAsString.getCharacterAtPosition(i); 
    if(i.mod(3)){//test to see if i when devided by 3 in an integer modulo, 
    separatedWithSpaces += " "; 

    }//end if 

}//end loop 

我知道這是不是在任何特定的語,但希望你的想法。

大衛

+1

我認爲正則表達式是解決這個問題的最好和最乾淨的方式。這聽起來太複雜了。 –

8

這裏是一個相當簡潔明瞭,如果你正在處理的整數另一種方法:

number.to_s.reverse.scan(/\d{1,3}/).join(",").reverse 

number   #=> 12345678 
.to_s    #=> "12345678" 
.reverse   #=> "87654321" 
.scan(/\d{1,3}/) #=> ["876","543","21"] 
.join(",")  #=> "876,543,21" 
.reverse   #=> "12,345,678" 

的整數的偉大工程。當然,這個特定的例子將用逗號分隔數字,但切換到空格或任何其他分隔符就像替換join方法中的參數一樣簡單。

+1

'''formatted_n = n.to_s.reverse.gsub(/...(?=.)/,'\&,')。reverse'''快於此解決方案;) – Matrix

+2

@Matrix這可能是爲什麼是對這個問題的最高回覆:)我剛剛加入了我對這個問題的看法。我愛Ruby,因爲總有一百種不同的方式來做事情! –

+1

你似乎把我的評論當作攻擊,它沒有,我只是閱讀各種解決方案,因爲「頂」並不總是最好的。所以我做了一個基準測試,我給出了我的結論,希望聽到它。沒有更多;) – Matrix

1

這是舊的,但我能找到這樣做的最快和最優雅的方式是:

def r_delim(s, e)                
    (a = e%1000) > 0 ? r_delim(s, e/1000) : return; s << a       
end 

r_delim([], 1234567).join(',') 

我會試着在某個時候加的基準。

2

除了其中一個答案以外,其餘都使用n.to_s。 @ MrMorphe's沒有,但是他創建了一個數組來編輯join。這是既不使用Fixnum#to_s也不使用Array#join的方式。

def separate(n,c=' ') 
    m = n 
    str = '' 
    loop do 
    m,r = m.divmod(1000) 
    return str.insert(0,"#{r}") if m.zero? 
    str.insert(0,"#{c}#{"%03d" % r}") 
    end 
end 

separate(1)  #=>   "1" 
separate(12)  #=>  "12" 
separate(123)  #=>  "123" 
separate(1234) #=>  "1 234" 
separate(12045) #=> "12 045" 
separate(123456) #=> "123 456" 
separate(1234000) #=> "1 234 000" 

嗯。這個專欄在右邊小費嗎?

使用to_s另一種方式,但不是join

def separate(n, c=' ') 
    str = n.to_s 
    sz = str.size 
    (3...sz).step(3) { |i| str.insert(sz-i, c) } 
    str 
end 
1

另一種方式: 這裏的 「分隔符是' '(空間),你可以用錢來換算指定','。」

number.to_s.reverse.gsub(%r{([0-9]{3}(?=([0-9])))}, "\\1#{delimiter}").reverse 
+0

@Unihedron感謝您的編輯。 – Pavan

+0

嘿,歡迎來到[so]!歡迎您,並祝賀您的​​第一次upvote(來自我:D)順便說一句,參加[旅遊],並且您可以在相關的[聊天室](http://chat.stackoverflow.com/)中聊天,一旦你有足夠的[聲譽](http://stackoverflow.com/help/whats-reputation)。 – Unihedron

0

我只是偶然發現了這個線程,同時尋找一種方法來將值格式化爲美元。我參加了一個稍微不同的方法所提出的解決方案,正則表達式:

amt = 1234567890.12 
f_amt = format("$%.2f",amt) 
i = f_amt.index(".") 
while i > 4 
    f_amt[i-3]=","+f_amt[i-3] 
    i = f_amt.index(",") 
end 

f_amt 
=> "$1,234,567,890.12" 

這可以參數化格式化其他貨幣。

相關問題