这段代码全部工作并产生11 22和2032。
date = '11-22-2032'
mon, day, year = $1, $2, $3 if date =~ /(\d\d)-(\d\d)-(\d\d)/
p mon,day,year
但这样的事情是行不通的:
str = "This is a string"
str.gsub!(/(\w+)/, "1#{$1}")
p str => prints all whitespace
Ruby是否从右边开始计算表达式(因此第一个示例的工作原理是什么?)如何使第二个示例工作(在同一个.gsub方法中使()包含在()中,所以我可以添加1每个字之前)?
您的第二个示例不起作用的事实与if
的评估顺序无关。
相反,使用\1
和\2
作为插值变量。
str = "This is a string"
str.gsub!(/(\w+)/, '1\1')
print str
还要注意"\1"
是插值的,你需要'\1'
。
我不认为gsub
以可替换字符串中使用的方式设置全局变量$1
,$2
等(请参阅http://www.ruby-doc.org/core-1.9.3/String.html#method-i-gsub)。相反,使用反向引用\1
(因为你将它们包含在双引号字符串中,你需要双重转义为"\\1"
):
>> str = "This is a string"
=> "This is a string"
>> str.gsub!(/(\w+)/, "1\\1")
=> "1This 1is 1a 1string"
您不能以这种方式使用$1
的原因是因为您将字符串作为arg传递到gsub
方法,这意味着它与插值的$1
一起在gsub
设置并使用之前进行评估。 @ berkes的答案是一种方式,可能是避免这种情况并获得匹配组的最佳方法。
但是,你也可以使用一个块:
str = "This is a string"
str.gsub!(/(\w+)/) {"1#{$1}"}
因为只有在调用时才会计算块,这将在gsub
已经执行匹配之后进行。