是否有将大量逗号加起来的窍门?


201

有没有一种方法可以让滑轨打印出带逗号的数字?

例如,如果我有一个数字54000000.34,则可以运行<%= number.function%>,它会打印出“ 54,000,000.34”

谢谢!

Answers:


353

您需要该number_with_delimiter方法。例如:

<%= number_with_delimiter(@number, :delimiter => ',') %>

或者,可以使用该number_with_precision方法来确保始终以两位小数精度显示数字:

<%= number_with_precision(@number, :precision => 2, :delimiter => ',') %>

5
@Mo这是一个视图助手方法。通过包含ActionView::Helpers::NumberHelper在模块中,您应该能够从模块中使用它。
约翰·托普利

9
我相信默认情况下,定界符是逗号,因此在这种情况下,您无需传递该选项。
Deekor

3
您应该关闭定界符,以便当前语言环境可以决定使用什么。这样可以正确显示使用分隔符使用句点的语言环境,而不是将他们认为的小数点放在数千之间。请参阅下面的coloradoblue答案。
凯尔·赫罗尼穆斯

1
Rails 4语法:<%= number_with_precision(@number,precision:0,delimiter:',')%>
Choylton B. Higginbottom

2
当心:number_with_delimiter过于复杂,而且速度非常慢,并且调用堆栈的深度很大。它曾经i18n能够格式化人类和地球外文明已知的任何数字(或者即使您将其指定为参数,也可能只是选择一个,.十进制数字)。它分配了成千上万个对象(因此其性能模式非常复杂且难以分析)。如果您不需要支持根据地区设置数字格式的其他方式,请考虑仅使用正则表达式。
kolen

133

对于不使用rails的任何人:

number.to_s.reverse.gsub(/(\d{3})(?=\d)/, '\\1,').reverse

2
真好 而你的答案似乎是微小的(只有一秒钟超过一百万次迭代的一小部分),比快的方法呈现在这里number.to_s.reverse.scan(/(?:\d*\.)?\d{1,3}-?/).join(',').reverse
user664833

你能解释一下发生了什么吗?number.to_s.reverse.gsub(/(\ d {3})(?= \ d)/,'\\ 1,')。reverse
Stephen Nguyen

7
当然,它会反转字符串,然后在任意3位数字序列之后添加一个逗号,然后再跟上另一位数字,然后将其反转。
pguardiario

1
@renosis-我明白您的意思了,这是用于格式化货币。所以2位小数,而不是7
pguardiario

2
@pguardiario \\ 1中有什么额外的\?还\1不够?谢谢。
butterywombat 2014年



24

如果要在视图之外添加逗号,并且不想包括某些模块,则可以使用number_to_delimited方法(rails版本> = 4.02)。例如:

#inside anywhere
ActiveSupport::NumberHelper.number_to_delimited(1000000) # => "1,000,000"

19

如果您不仅要这样做,而且还想做很多事情,因为上面没有暗示,那么Rails会为该number_with_delimiter方法提供合理的默认值。

#inside controller or view
number_with_delimiter(2444323.4)
#=> 2,444,323.30

#inside console
helper.number_with_delimiter(233423)
#=> 233,423

如果您以最典型的方式进行操作,则无需提供定界符值。


这具有使用当前语言环境的额外好处。这在国际应用程序中确实非常重要,因为某些语言环境使用逗号表示小数,使用句点表示千位分隔符。
凯尔·赫罗尼穆斯

16

对于不使用会处理小数的rails的人来说,更好的方法是:

parts = number.to_s.split('.')
parts[0].gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1,")
parts.join('.')

如果要使用其他定界符,请在正则表达式中更改最后一个','。

对于奖金,这是正则表达式的工作方式:

  • gsub将传递给gsub的第二个参数替换与正则表达式匹配的所有内容。在这种情况下是\\1。在评估时\\1变为\1与正则表达式中的第一个捕获组匹配。在这个正则表达式中(\d)
  • (\d)(?=(\d\d\d)+)匹配一个数字,然后是1个或多个3位数字的组。第一组是我们的\1捕获组,第二组是\2。如果我们只保留它,则会得到: 123456.gsub!(/(\d)(?=(\d\d\d)+)/, "\\1,") #=> 1,2,3,456这是因为1234个匹配项,2345个匹配项和3456个匹配项,所以我们在1、2和3后面加上逗号。
  • 通过添加(?!\ d),我们可以匹配之前没有出现在数字之前的所有内容,因此(\d)(?=(\d\d\d)+(?!\d))意味着匹配一个数字后跟3个数字,而后跟一个数字。之所以起作用,是因为gsub将继续替换与字符串匹配的内容。如果我们只打算替换第一个匹配项,那么对于123456789这样的数字,我们将得到123456,789。由于123456,789仍然与我们的正则表达式匹配,因此我们得到123,456,789。

这是我得到代码的地方:https : //github.com/rails/rails/blob/master/activesupport/lib/active_support/number_helper.rb#L298-L300

在这里,我了解了该正则表达式中发生的情况:http : //www.tutorialspoint.com/ruby/ruby_regular_expressions.htm


就像魅力一样工作,尤其是在Liquid模板lang中:{{ value | round | replace: "(\d)(?=(\d\d\d)+(?!\d))", "$1," | prepend: "$" }}
Kukunin

2

另一个不使用Helpers的解决方案:格式化2个小数位,然后替换。通过,

puts(("%.2f" % 2.5666).gsub('.',','))
>> 2,57

1
我相信问题是关于数字分组的逗号,而不是您的答案所达到的作为整数部分/分数部分小数点分隔符的逗号。(正如该Wiki链接所解释的那样,由于长期以来的混乱,互联网标准现在建议仅将空格用于数字分组)
Beni Cherniavsky-Paskin,

1

您可以使用以下方法 ActiveSupport

例如:

ActiveSupport::NumberHelper::number_to_currency(10000.1234,{precision: 2,unit: ''})


1
  def add_commas(numstring)
    correct_idxs = (1..100).to_a.select{|n| n % 6 == 0}.map{|n| n - 1}
     numstring.reverse.chars.join(",").chars.select.with_index{|x, i| i.even? || correct_idxs.include?(i)}.join.reverse
  end

这是我的红宝石方式

加法编辑:基本上,它会在数字之间添加所有逗号,并且仅选择索引+ 1%6的那些逗号

我认为逗号最多可以使用100,但是如果您想要一个超长的数字,只需将100设为一个更大的数字



0

以下是定界符和精度(API ref)的技巧。

ActiveSupport::NumberHelper.number_to_rounded(1234.532, delimiter: ',', precision: 1) 

(或仅从视图开始number_to_rounded,无需后缀)

高温超导


-1

对于javascript族

function numberWithDelimiter(value) {
    return (value+"").split("").reverse().join("").replace(/(\d{3})(?=\d)/g, '$1,').split("").reverse().join("")
}

:)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.