如何在Ruby中输出前导零?


238

我正在从Ruby脚本输出一组编号文件。这些数字来自增加一个计数器,但是为了使它们在目录中排序良好,我想在文件名中使用前导零。换一种说法

file_001 ...

代替

文件_1

将数字转换为字符串时,是否有一种简单的方法可以添加前导零?(我知道我可以做“如果小于10...。如果小于100”)。

Answers:


281

如果知道计数器中的最大位数(例如,对于计数器1..876,n = 3),则可以执行

str = "file_" + i.to_s.rjust(n, "0")

8
呵呵,不是最好的答案,但是我不知道正义,我已经使用红宝石多年了。干杯!
pauliephonic

之所以投票,是因为%03s似乎出于某种奇怪的原因而用空格填充了(%03d似乎可以正常工作)。在两种情况下,我都可以宣誓C填充零。
Nerdmaster 2013年

最后,将其切换为可接受的答案,因为它是最简单,最容易记住的。%有效,但用途更广泛。
弥敦道(Nathan Long)

出乎意料,但最简单
akostadinov

1
来到这里了解如何填充基数36。这适用于此,而%看起来却不行。谢谢!
伊桑·卡明斯基

344

%字符串使用运算符:

irb(main):001:0> "%03d" % 5
=> "005"

左侧是printf格式的字符串,右侧可以是值列表,因此您可以执行以下操作:

irb(main):002:0> filename = "%s/%s.%04d.txt" % ["dirname", "filename", 23]
=> "dirname/filename.0023.txt"

这是一个printf格式备忘单,您可能会发现它对形成格式字符串有用。printf格式最初来自该C函数printf,但是在perl,ruby,python,java,php等中也可以使用类似的格式化功能。


1
大!因此,“%s”表示“在此替换第N个值”,而“%03d”表示“在此替换一个数字,添加所需数量的零以使其成为3位数?” (我猜d的意思是“数字”。)我现在看到了有关此文档(ruby-doc.org/core/classes/String.html#M000770),但是它非常简洁,我想做一点阐述。
内森·朗2009年

1
我添加了一个指向printf格式备忘单的链接。“ s”表示“字符串”,“ d”表示“十进制数”。“ 03”的意思是“填充到零的3个字符”;“%3d”将在左侧用空格填充。
Daniel Martin

2
顺便说一句-这与calling相同Kernel#sprintf,在此处记录:ruby-doc.org/core-1.9.3/Kernel.html#method-i-sprintf
Nathan Long,

除了@NathanLong的评论外,此答案中的第一个示例将写为sprintf("%03d", 5)
丹尼斯

这应该是选定的答案。
丹·巴伦

50

您不能在连接文件名之前就使用值的字符串格式吗?

"%03d" % number

我认为此答案不会为@Daniel Martin的答案添加任何内容,但是我喜欢它的简单性……
svelandiag 2016年

3
他与丹尼尔·马丁(Daniel Martin)在同一分钟回答,因此可能没有意识到重复。
Kurt Peek

这非常适合utc_offset
Abel

30

使用String#next作为计数器。

>> n = "000"
>> 3.times { puts "file_#{n.next!}" }
file_001
file_002
file_003

next 相对“聪明”,这意味着您甚至可以

>> n = "file_000"
>> 3.times { puts n.next! }
file_001
file_002
file_003

感谢您指出了这一点。这是一个很棒的方法。
Weston Ganger

9

如其他答案所述,"%03d" % number效果很好,但是与rubocop 红宝石风格指南背道而驰:

相对于相当隐秘的String#%方法,建议使用sprintf及其别名格式

我们可以使用以下方法以更易读的方式获得相同的结果:

format('%03d', number)

1
如果您的目标是学习晦涩的Ruby语言功能,请使用别名format。如果您的目标是使代码易于理解,则应使用sprintf,因为它是标准C库的一部分。跨编程语言使用此名称。sprintf与知道这format是别名的人相比,更多的人了解它的作用。仅仅因为某事是RuboCop的一部分,并不能使其固有地对或错。选择最适合您的项目的规则。'%03d' % number更容易阅读。
Tilo

1
我经历了同样的循环,更改"%02d" % numsprintf(...),然后format(...)根据RuboCop的建议进行了更改。然后,我认为它sprintf比常规format,所以用更新了rubocop.yml,Style/FormatString: EnforcedStyle: sprintf现在我晚上睡得好。
David Hempy

1

filenames = '000'.upto('100').map { |index| "file_#{index}" }

产出

[file_000, file_001, file_002, file_003, ..., file_098, file_099, file_100]

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.