我有一个字符串,例如02112016.我想从这个字符串中创建一个日期时间。
我试过了:
s = "02112016"
s.sub(/(\d{2})(\d{2})(\d{4})/, "#{$1}-#{$2}-#{$3}")
但是有一个问题。它返回"--"
。
如果我再次尝试此s.sub(/(\d{2})(\d{2})(\d{4})/, "#{$1}-#{$2}-#{$3}")
,则有效:"02-11-2016"
。现在我可以使用to_datetime方法。
但为什么s.sub(/(\d{2})(\d{2})(\d{4})/, "#{$1}-#{$2}-#{$3}")
第一次没有工作?
答案 0 :(得分:4)
这真的是一个简单的改变。 $1
和朋友只有在匹配成功后才会被分配,而不是在匹配期间。如果要使用立即值,请执行以下操作:
s = "02112016"
s.sub(/(\d{2})(\d{2})(\d{4})/, '\1-\2-\3')
# => "02-11-2016"
此处\1
对应 分配给$1
的内容。如果您使用的是gsub
,这一点尤其重要,因为$1
往往只是最后一次匹配,而\1
则是针对每个匹配进行评估。
答案 1 :(得分:3)
我更喜欢以下内容。
r = /
\d{2} # match two digits
(?=\d{4}) # match four digits in a positive lookahead
/x # free-spacing regex definition mode
与
相同r = /\d{2}(?=\d{4})/
与String#gsub一起使用:
s.gsub(r) { |s| "#{s}-" }
试一试:
"02112016".gsub(r) { |s| "#{s}-" }
#=> "02-11-2016"
答案 2 :(得分:2)
第一次运行时发生了什么,Context
,$1
和$2
为空
你基本上是为空字符串提供数字。
所以如果我们这样做
$3
这就是它第二次运作的原因。
由于字符串的长度始终相同,因此您可以使用s = "02112016"
p $1 #=> nil
p $2 #=> nil
p $3 #=> nil
s.sub(/(\d{2})(\d{2})(\d{4})/, "#{$1}-#{$2}-#{$3}") #=> "--"
p $1 #=> "02"
p $2 #=> "11"
p $3 #=> "2016"
s.sub(/(\d{2})(\d{2})(\d{4})/, "#{$1}-#{$2}-#{$3}") #=> "02-11-2016"
方法将其分解。
[]
这将返回所需的结果
s = "#{s[0..1]}-#{s[2..3]}-#{s[4..-1]}"