在Ruby中评估表达式

问题描述 投票:0回答:3

这段代码全部工作并产生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每个字之前)?

ruby string gsub
3个回答
2
投票

您的第二个示例不起作用的事实与if的评估顺序无关。

相反,使用\1\2作为插值变量。

str = "This is a string"
str.gsub!(/(\w+)/, '1\1')
print str

还要注意"\1"是插值的,你需要'\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"

0
投票

您不能以这种方式使用$1的原因是因为您将字符串作为arg传递到gsub方法,这意味着它与插值的$1一起在gsub设置并使用之前进行评估。 @ berkes的答案是一种方式,可能是避免这种情况并获得匹配组的最佳方法。

但是,你也可以使用一个块:

str = "This is a string"
str.gsub!(/(\w+)/) {"1#{$1}"}

因为只有在调用时才会计算块,这将在gsub已经执行匹配之后进行。

© www.soinside.com 2019 - 2024. All rights reserved.