{}之间有什么关系?

时间:2013-05-24 20:16:01

标签: ruby

有一段代码:

 def test_sub_is_like_find_and_replace
    assert_equal "one t-three", "one two-three".sub(/(t\w*)/) { $1[0, 1] }
 end

我发现很难理解{ }大括号之间的区别。有人能解释一下吗?

3 个答案:

答案 0 :(得分:5)

{...}是一个块。 Ruby会将匹配的值传递给块,并将块的返回值替换回字符串。 String#sub文档更全面地解释了这一点:

  

在块形式中,当前匹配字符串作为参数传入,并且将适当地设置诸如$ 1,$ 2,$`,$&和$'的变量。块返回的值将替换每次调用的匹配。

编辑:根据迈克尔的评论,如果你对$1[0, 1]感到困惑,这只是第一次捕获($1)并获取它的子串(特别是第一个字符)。 $ 1是一个全局变量,设置为正则表达式后的第一个捕获的内容(以真正的Perl方式),并且因为它是一个字符串,#[]运算符用于从索引0开始获取它的子字符串,长度为1。

答案 1 :(得分:2)

sub方法要么带两个参数,首先是要替换replace的文本,第二个是替换,或者一个参数是要替换的文本,以及一个定义如何处理替换的块。

如果您不能将替换定义为简单字符串,则块方法很有用。

例如:

"foo".sub(/(\w)/) { $1.upcase }
# => "Foo"

"foo".sub(/(\w+)/) { $1.upcase }
# => "FOO"

gsub方法的工作方式相同,但适用次数不止一次:

"foo".gsub(/(\w)/) { $1.upcase }
# => "FOO"

在所有情况下,$1都是指括号(\w)捕获的内容。

您的代码,图示

r = "one two-three".sub(/(t\w*)/) do 
  $1 # => "two"
  $1[0, 1] # => "t"
end

r # => "one t-three"

答案 2 :(得分:0)

sub正在使用正则表达式。 $1是一个保留的全局变量,包含正则表达式的匹配。

括号表示一个代码块,用于将匹配替换为块返回的字符串。在这种情况下

puts $1
#=> "two"
puts $1[0, 1]
#=> "t"