我需要一种格式化数字的方法。我在我的数据库表中存储了一些数字,例如12500
,并希望以此格式12 500
打印它们(因此每3位数字就有一个空格)。是否有一种优雅的方式来做到这一点?
答案 0 :(得分:36)
请参阅:http://www.justskins.com/forums/format-number-with-comma-37369.html
没有内置的方法(除非你使用Rails,ActiveSupport有方法可以做到这一点)但你可以使用像这样的正则表达式
formatted_n = n.to_s.reverse.gsub(/...(?=.)/,'\&,').reverse
答案 1 :(得分:21)
Activesupport使用此正则表达式(并且没有反向反转)。
10000000.to_s.gsub(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1 ") #=> "10 000 000"
答案 2 :(得分:9)
如果你正在处理整数,这里的另一种方法相当简洁明了:
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
方法中的参数一样简单。
答案 3 :(得分:8)
official document提出了三种不同的方式:
1)使用lookbehind和lookahead(需要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"
答案 4 :(得分:4)
非常简单:
number_with_delimiter(12500, delimiter: " ")
请参阅:http://apidock.com/rails/ActionView/Helpers/NumberHelper/number_with_delimiter
答案 5 :(得分: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
答案 6 :(得分:3)
另一种方式:
12500.to_s.reverse().split(//).inject() {|x,i| (x.gsub(/ /,"").length % 3 == 0 ) ? x + " " + i : x + i}.reverse()
您可以随时打开Fixnum类并为方便起见添加它:
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"
答案 7 :(得分:2)
其中一个答案都使用n.to_s
。 @MrMorphe没有,但他创建了一个阵列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
答案 8 :(得分:1)
这是旧的,但我能找到的最快,最优雅的方式是:
def r_delim(s, e)
(a = e%1000) > 0 ? r_delim(s, e/1000) : return; s << a
end
r_delim([], 1234567).join(',')
我会尝试在某些时候添加基准测试。
答案 9 :(得分:1)
另一种方式:
此处“分隔符为' '
(空格),您可以指定','
进行货币转换。”
number.to_s.reverse.gsub(%r{([0-9]{3}(?=([0-9])))}, "\\1#{delimiter}").reverse
答案 10 :(得分: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"
这可以参数化以格式化其他货币。
答案 11 :(得分:-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
我知道这不是任何特定的语言,但希望你能得到这个想法。
大卫