有一段代码:
def test_sub_is_like_find_and_replace
assert_equal "one t-three", "one two-three".sub(/(t\w*)/) { $1[0, 1] }
end
我发现很难理解{ }
大括号之间的区别。有人能解释一下吗?
答案 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"