我有一个b1 b2 b3 b4
8 NA NA 7
对象,它有一个持续时间属性(基于字符串),以分钟和秒为单位。我想将此输出为Song
标签的datetime
属性(通过Rails),但需要将其转换为ISO 8601格式才能使其在语义上有效。
所以,我有持续时间<time/>
。在删除两个数字之间的冒号并最后在结尾附加字母"2:30"
时,需要预先设置字符'PT'
:
'S'
最终输出:
PT2M30S
我将如何实现这一目标?
是否有Ruby方法可以实现这一目标?是否必须写出正则表达式才能找到/替换上述字符?
答案 0 :(得分:2)
如果你想以优雅的方式做到这一点,试试ruby-duration gem
示例代码
Duration.new(:weeks => 1, :days => 20).iso8601 => "P3W6DT0H0M0S"
答案 1 :(得分:2)
它没有采用正则表达式或任何想要做的事情。我只是简单地拆分冒号,并将结果传递给格式字符串:
'PT%sM%sS' % "2:30".split(':') # => "PT2M30S"
在这种情况下,模运算符如何工作?从来没有见过这样的事情。
它不是&#34;模运算符&#34;除非它被应用于一个数字。它是一个名为%
的String方法,相当于format
或sprintf
。有关详细信息,请参阅String.%
后跟Kernel::sprintf
,但基本上是:
s | Argument is a string to be substituted. If the format
| sequence contains a precision, at most that many characters
| will be copied.
所以:
'%s' % 'foo' # => "foo"
'%5s' % 'foo' # => " foo"
'%-5s' % 'foo' # => "foo "
'%1s' % 'foo' # => "foo"
'%.1s' % 'foo' # => "f"
'%s = %s' % ['a', 1] # => "a = 1"
请特别注意,在插入字符串时,最后一个1
会转换为"1"
。这可能很有用,但它不是从对象转换为字符串的唯一方式(甚至是更好的方式)。
最后,不要假设正则表达式是解决每个需要从字符串中提取信息的问题的方法。如果您可以在不使用奇怪的解决方法的情况下执行此操作,请使用内置方法,例如split
:
require 'fruity'
compare do
_split { 'PT%sM%sS' % "2:30".split(':') }
_regex { "2:30".sub(/(.*):(.*)/, "PT\\1M\\2S") }
end
结果是:
# >> Running each test 2048 times. Test will take about 1 second.
# >> _split is faster than _regex by 19.999999999999996% ± 10.0%
正则表达式很灵活,但通常以降低速度为代价。
此外,当gsub
应该被使用时,我们会发现很多误导sub
。 sub
的工作量比gsub
少得多;如果sub
触发一次,gsub
将继续循环,直到它到达字符串的末尾。这是一个可衡量的差异,即使在诸如"2:30"
:
compare do
_sub { "2:30".sub(/(.*):(.*)/, "PT\\1M\\2S") }
_gsub { "2:30".gsub(/(.*):(.*)/, "PT\\1M\\2S") }
end
# >> Running each test 2048 times. Test will take about 1 second.
# >> _sub is faster than _gsub by 2x ± 0.1
答案 2 :(得分:1)
我会把它变成一种方法......
> "2:30".sub(/(.*):(.*)/, "PT\\1M\\2S")
=> "PT2M30S"