Regex第一次没有工作

时间:2016-11-03 00:26:49

标签: ruby regex

我有一个字符串,例如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}")第一次没有工作?

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]}"