如何将数字 1000 格式化为“1 000”

发布于 2024-11-17 01:03:18 字数 123 浏览 1 评论 0原文

我需要一种格式化数字的方法。我在数据库表中存储了一些数字,例如 12500,并希望以 12 500 格式打印它们(因此每 3 位数字有一个空格)。有没有一种优雅的方法来做到这一点?

I need a way to format numbers. I stored some numbers in my DB table, e.g. 12500, and would like to print them in this format 12 500 (so there is a space every 3 digits). Is there an elegant way to do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

风渺 2024-11-24 01:03:18

没有内置的方法(除非您使用 Rails,ActiveSupport 确实有方法来做到这一点),但您可以使用正则表达式,例如

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

There is no built in way to it ( unless you using Rails, ActiveSupport Does have methods to do this) but you can use a Regex like

formatted_n = n.to_s.reverse.gsub(/...(?=.)/,'\&,').reverse
对岸观火 2024-11-24 01:03:18

Activesupport 使用此正则表达式(并且没有反向反向)。

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

Activesupport uses this regexp (and no reverse reverse).

10000000.to_s.gsub(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1 ") #=> "10 000 000"
涫野音 2024-11-24 01:03:18

如果您处理整数,这是另一种相当简洁明了的方法:

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 方法中的参数一样简单。

Here's another method that is fairly clean and straightforward if you are dealing with integers:

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"

Works great for integers. Of course, this particular example will separate the number by commas, but switching to spaces or any other separator is as simple as replacing the parameter in the join method.

梦初启 2024-11-24 01:03:18

官方文档提出了三种不同的方式:

1)使用lookbehind和lookahead(需要oniguruma)

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

2) 仅使用前瞻。与 steenslag 的答案相同。

3)既不使用lookahead也不使用lookbehind

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

The official document suggests three different ways:

1) Using lookbehind and lookahead (Requires oniguruma)

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

2) Using only lookahead. Identical to steenslag's answer.

3) Using neither lookahead nor lookbehind

s = 12500.to_s
nil while s.sub!(/(.*\d)(\d{3})/, '\1 \2')
s # => "12 500"
你不是我要的菜∠ 2024-11-24 01:03:18

非常简单:

number_with_delimiter(12500, delimiter: " ")

请参阅: http://apidock.com/rails/ActionView/Helpers/NumberHelper/number_with_delimiter

very simple:

number_with_delimiter(12500, delimiter: " ")

see: http://apidock.com/rails/ActionView/Helpers/NumberHelper/number_with_delimiter

梦中的蝴蝶 2024-11-24 01:03:18

另一种方法:

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"

Another way:

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

You can always Open the Fixnum class and add this for convenience:

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"
土豪我们做朋友吧 2024-11-24 01:03:18

所以,这非常疯狂和黑客,但它完成了工作......

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

So, this is pretty crazy and hackish, but it gets the job done...

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
蛮可爱 2024-11-24 01:03:18

除一个答案外,所有答案均使用 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

All but one of the answers use n.to_s. @MrMorphe's does not, but he creates an array to be joined. Here's a way that uses neither Fixnum#to_s nor 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"

Hmmm. Is that column on the right tipping?

Another way that uses to_s but not join:

def separate(n, c=' ')
  str = n.to_s
  sz = str.size
  (3...sz).step(3) { |i| str.insert(sz-i, c) }
  str
end
倾听心声的旋律 2024-11-24 01:03:18

这是旧的,但我能找到的最快、最优雅的方法是:

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

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

我将尝试在某个时候添加基准。

This is old but the fastest and most elegant way I could find to do this is:

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

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

I'll try and add benchmarks at some point.

篱下浅笙歌 2024-11-24 01:03:18

另一种方式:
这里“分隔符是' '(空格),可以指定','进行货币换算。”

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

Another way:
Here "delimiter is ' '(space), you can specify ',' for money conversion."

number.to_s.reverse.gsub(%r{([0-9]{3}(?=([0-9])))}, "\\1#{delimiter}").reverse
[浮城] 2024-11-24 01:03:18

我只是在寻找一种将值格式化为美国货币的方法时偶然发现了这个线程。我对所提出的正则表达式解决方案采取了略有不同的方法:

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"

这可以参数化以格式化其他货币。

I just stumbled on this thread while looking for a way to format a value as US currency. I took a slightly different approach to the regex solutions proposed:

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"

This could be parameterized for formatting other currencies.

冷…雨湿花 2024-11-24 01:03:18

我知道这是一个老问题但是。

为什么不直接使用子字符串替换。

用伪代码......

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

我知道它不是用任何特定的语言,但希望你能明白。

大卫

I'm aware this is an old question but.

why not just use a substring substitution.

in pseudo code....

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

I know it isn't in any particular languange, but hopefully you get the idea.

David

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文